ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
have a problem with a simple client-server application.
the server should run endless, like demon or background process:
Code:
/* server.c */
int main (void)
{
while (1) {
/* do some stuff with serial port */
}
return 0;
}
the cgi-client should start the server:
Code:
/* cgi_test.c */
int main (void)
{
pid_t pid;
pid = fork();
/* if we are child, start the server */
if (pid == 0) {
execl ("/bin/server", "server", NULL);
}
/* if we are parent, say server has started */
else {
printf ("Content-type: text/plain\n\r\n");
printf ("Server started\n");
}
return 0;
}
Seems not very difficult...
So, when i type for example the browser-url:
http ://192.168.99.127/cgi-bin/cgi_test
the server really starts (can be seen with ps) but i do not get the "Server startet" text in the browser unless i kill the server process, then the text appears.
So it seems that the text is send to the browser not until the complete "cgi_test" process including child processes finished.
But the server should stay working.
I already tried to:
- exchange execl with system: same effect.
- insert a fsync(1) after the printf(): same effect.
What can i do to get the server process be adopted by the init process?
Or whatelse do i make wrong?
Any help greatly appreciated.
Klopfer
P.S. the "server" is not the webserver which handles the cgi_test program, of course.
unless (fork) {
# this is the child (launching process)
print "Starting daemon process $$ $hostname ",scalar localtime,"\n";
unless (fork) {
# this is the child's child (daemon process)
sleep 1 until getppid == 1;
run_daemon(); # this is the heart of the daemon process. It assumes full control until told to quit.
exit 0;
}
# first child exits quickly - forks daemon and quits
exit 0;
}
wait; # parent reaps firsst child quickly - launcher quits, parent is done
It is what I use to launch daemon processes in perl scripts. The main purpose was for client<>server control programs, but it should work as a cgi script as well.
Last edited by GrueMaster; 03-29-2007 at 12:09 PM.
Does the cgi-test process show up in the process table until the child server process terminates? Not too sure where to go from there, but it might be revealing. Are you doing anything to prevent polluting the process table with zombie processes? I forget exactly what the procedure is, but perhaps it may have the beneficial side effect of fixing your problem. Have you tried 'exit(0)', instead of simply 'return(0)'? I'm not sure if there is a semantic difference, but maybe worth a shot.
--- rod.
GrueMaster:
I'm not sure to completely understand your perl script, but i think the main difference is that you use fork twice (child of child)?
Will test if this could help...
Rod:
Quote:
Originally Posted by theNbomr
Does the cgi-test process show up in the process table until the child server process terminates?
No, the parent (cgi-test) process terminates first, so there's only the server in the process list.
Quote:
Are you doing anything to prevent polluting the process table with zombie processes?
No, i do not, but already tried to wait for the child to finish (i think that's the normal way to prevent zombies) but this didn't work as well because the server will not terminate so cgi-test then simply waits endless and produces no output too.
Quote:
Have you tried 'exit(0)', instead of simply 'return(0)'?
Yes, tried exit and return both in cgi-test. No difference
You were right, i never get output when using 'return(0)'.
With 'exit(0)' i get output... but still only when i kill the server.
(tried so much that i was confused about the results belonging to tested things)
By the way, putting an extra-fork inside the server did not help
Actual code:
Code:
/* server.c */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
pid_t pid;
pid = fork();
if (pid != 0) // exit if we are parent or on error
exit(EXIT_SUCCESS);
fclose (stdout); // <== this was the cruical command
while (1) {
/* do some stuff with serial port */
}
return 0;
}
Code:
/* cgi_test.c */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
pid_t pid;
pid = fork();
/* if we are child, start the server */
if (pid == 0) {
execl ("/bin/server", "server", NULL);
}
/* if we are parent, say server has started */
else {
printf ("Content-type: text/plain\n");
printf ("\r\n\r\n");
printf ("Server started\n");
}
exit (EXIT_SUCCESS); //0
}
Okay, now I'm kind of spitballing, but that's about all I've got left.
In your server process, it will inherit the stdout file descriptor from the cgi_test parent. I'm thinking that somehow, this keeps the webserver from seeing 'eof' on the file it is reading to capture the cgi output. Perhaps if you close()/reopen()/dup() the stdout file descriptor in the server process, it will sever the ties with the webserver, and allow it to procede. I hope this makes some sense, and I'm sorry I can't lay out a detailed recipe, but maybe it helps. If not, I hope someone else can jump in here.
... Perhaps if you close()/reopen()/dup() the stdout file descriptor in the server process, it will sever the ties with the webserver, and allow it to procede. I hope this makes some sense, ...
Wow, thank you very much rod.
Yes, indeed, this makes much sense - and now it's working :-)
thx again,
Rainer
P.S. Edited the above code to reflect how it works now.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.