.rhavin has asked for the wisdom of the Perl Monks concerning the following question:

Solved Question - Working Solution:

In order to spawn a deamon from cgi, all filehandles must get closed to completely detach from httpd. In this case, carpout'ing error log shiftet the original (and therefore still open) STDERR to CGI::Carp::SAVEERR and had to get closed also.

# ------------------------------------------------ # spawn completely detached deamon sub BaseForkDeamon { return 1 if (fork()); POSIX::setsid(); close STDOUT; close STDIN; close STDERR; close CGI::Carp::SAVEERR; # <-- close LOG return 0; };

Original Question

Hello monks... after reading for 3h thru google i still got no clue how to solve this problem ... or at least: how to do it in perl;-)

It's like this: # ------------------------------------------------ # spawns a deamon sub ForkDeamon { return 1 if (fork()); POSIX::setsid(); close STDOUT; close STDIN; close STDERR; return 0; };

That fn should fork a deamon and detach it from the calling browser in a web/cgi-skript. the problem is: it still blocks the handling httpd.
What i did understand from reading (belive to understand?) is that on fork *all* handles become copied and so my deamon still has the ports open socket. So my next try would be to close that socket and i did some googling for 'perl get port handle', because i also dont know how to obtain the HANDLE for the already open PORT and to make things a litle bit worser (at least for a non-native-speaker like me), 'port' is not a very specific search-word (i dont want to get info about how to port from/to perl) and what i really want to do is something like 'please close ALL currently open handles' - but i dont know how to do that either;-)

So, a solution for my problem would be ... nice.

The webserver of my ISP runs Apache/2.2.3 (Debian), the only Apache modules for perl i have are Apache::SOAP and Apache::XMLRPC::Lite.

thx,
~.rhavin;)

PS: should i have infringed some well known rules here, please bear in mind: it's my first posting...;-/

Replies are listed 'Best First'.
Re: fork/web-cgi: how do i close all open sockets in deamon?
by almut (Canon) on Jan 25, 2010 at 11:31 UTC

    Under normal circumstances, what you've done (in particular, closing STDOUT and STDERR) should be sufficient to detach a forked CGI script.  In order to further debug the issue you could try lsof — e.g. lsof -p<PID> to show files/pipes/etc. associated with process number PID (i.e. your CGI process that presumably causes httpd to hang).

    BTW, what's the exact context? Is this a regular CGI script, or called from within a mod_perl handler, or are you running the CGI script via mod_perl registry, etc.?  Is there a database involved (DBI/DBD::*)?

      thx for helping, i did what you suggested, but im not quite shure what to do with the obtained information ... i did a lsof right after forking with the pid of the child and got that:


      COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
      camtest.c 18397 web39 cwd DIR 0,23 2048 263424456 /var/www/web39/html/cgi-bin
      camtest.c 18397 web39 rtd DIR 0,23 1024 37650436 /
      camtest.c 18397 web39 txt REG 0,23 1061700 37766238 /usr/bin/perl
      camtest.c 18397 web39 mem REG 0,23 67364 38240776 /lib/tls/libresolv-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 17840 38240762 /lib/tls/libnss_dns-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 38372 38240764 /lib/tls/libnss_files-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 126656 37733628 /usr/lib/libexpat.so.1.0.0
      camtest.c 18397 web39 mem REG 0,23 19764 386252810 /usr/lib/perl/5.8.8/auto/Socket/Socket.so
      camtest.c 18397 web39 mem REG 0,23 96276 37749838 /usr/lib/perl5/auto/XML/Parser/Expat/Expat.so
      camtest.c 18397 web39 mem REG 0,23 111304 110919694 /usr/lib/perl/5.8.8/auto/POSIX/POSIX.so
      camtest.c 18397 web39 mem REG 0,23 32664 236503042 /usr/lib/perl/5.8.8/auto/Encode/Encode.so
      camtest.c 18397 web39 mem REG 0,23 21868 38240738 /lib/tls/libcrypt-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 1245488 38240734 /lib/tls/libc-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 85010 38240774 /lib/tls/libpthread-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 145136 38240754 /lib/tls/libm-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 9592 38240752 /lib/tls/libdl-2.3.6.so
      camtest.c 18397 web39 mem REG 0,23 15640 386301956 /usr/lib/perl/5.8.8/auto/IO/IO.so
      camtest.c 18397 web39 mem REG 0,23 88164 38240648 /lib/ld-2.3.6.so
      camtest.c 18397 web39 0r REG 0,23 12980 376176656 /usr/share/perl5/HTTP/Request/Common.pm
      camtest.c 18397 web39 1u IPv4 3040810374 UDP server2.alido.de:44066->ns1.vpsadmin.de:domain
      camtest.c 18397 web39 3w REG 0,23 1554 263423062 /var/www/web39/html/cgi-bin/test.err
      camtest.c 18397 web39 4w FIFO 0,7 3040810341 pipe

      is 'device 3040810374' the handle i look for? how can i close it? i dont have mod_perl, its a cgi-scipt w/o any open db.

        I *think* i found it .. /var/www/web39/html/cgi-bin/test.err is the carp-out ... after commenting out the carping, it worked ... so the deamon just has to close that handle, too. Thanks for helping in getting the answer.