LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 03-29-2007, 11:41 AM   #1
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6

Rep: Reputation: 0
Problem with fork() in cgi program


Hi all,

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.

Last edited by klopfer; 03-29-2007 at 11:52 AM.
 
Old 03-29-2007, 01:07 PM   #2
GrueMaster
Member
 
Registered: Aug 2005
Location: Oregon
Distribution: Kubuntu.
Posts: 848

Rep: Reputation: 30
Try tis snippit of code:

Code:
      
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 01:09 PM.
 
Old 03-29-2007, 01:14 PM   #3
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,396
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
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.
 
Old 03-29-2007, 02:07 PM   #4
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6

Original Poster
Rep: Reputation: 0
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

Rainer
 
Old 03-29-2007, 03:22 PM   #5
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6

Original Poster
Rep: Reputation: 0
Sorry Rod, beg your pardon.

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
}
Rainer

Last edited by klopfer; 03-30-2007 at 10:00 AM.
 
Old 03-29-2007, 04:40 PM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,396
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
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.

--- rod.
 
Old 03-30-2007, 09:57 AM   #7
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by theNbomr
... 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.
 
  


Reply

Tags
cgi, cgibin, fork, processes


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
cgi the program on C ++, compressed HTTP Roman_Rus Programming 5 07-22-2005 04:41 PM
How to fork a program and tell when it's done? tonyfreeman Programming 5 09-01-2004 11:25 PM
why my cgi program in c language can not run? nickhx Programming 9 08-03-2004 05:58 AM
C++ CGI Program(Tell Me what you think) karlan Programming 0 03-29-2004 02:33 PM
CGI program not work in Apache Manuel Tejada Linux - General 3 10-31-2002 09:32 PM


All times are GMT -5. The time now is 02:34 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration