LinuxQuestions.org
Share your knowledge at the LQ Wiki.
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

Tags used in this thread
Popular LQ Tags , , ,

Reply
 
Thread Tools
Old 03-29-2007, 11:41 AM   #1
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6
Thanked: 0
Problem with fork() in cgi program


[Log in to get rid of this advertisement]
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..
klopfer is offline  
Tag This Post , , ,
Reply With Quote
Old 03-29-2007, 01:07 PM   #2
GrueMaster
Member
 
Registered: Aug 2005
Location: Oregon
Distribution: Mandriva 2007. Others are now being tested through Xen. 2 Gigs of Ram is enough to run 3 OS's.
Posts: 847
Thanked: 0
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..
GrueMaster is offline     Reply With Quote
Old 03-29-2007, 01:14 PM   #3
theNbomr
Senior Member
 
Registered: Aug 2005
Distribution: Open Suse, Fedora, Redhat
Posts: 2,272
Thanked: 74
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.
theNbomr is offline     Reply With Quote
Old 03-29-2007, 02:07 PM   #4
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6
Thanked: 0

Original Poster
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
klopfer is offline     Reply With Quote
Old 03-29-2007, 03:22 PM   #5
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6
Thanked: 0

Original Poster
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..
klopfer is offline     Reply With Quote
Old 03-29-2007, 04:40 PM   #6
theNbomr
Senior Member
 
Registered: Aug 2005
Distribution: Open Suse, Fedora, Redhat
Posts: 2,272
Thanked: 74
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.
theNbomr is offline     Reply With Quote
Old 03-30-2007, 09:57 AM   #7
klopfer
LQ Newbie
 
Registered: Mar 2007
Location: Germany
Posts: 6
Thanked: 0

Original Poster
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.
klopfer is offline     Reply With Quote

Reply

Bookmarks


Thread Tools

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 09:18 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
RSS2  LQ Podcast
RSS2  LQ Radio
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration