|Keep It Simple, Stupid|
Re: close_on_exec in Perl : close socket opened in parent process when fork child , is not workingby eyepopslikeamosquito (Canon)
|on Jan 17, 2013 at 11:18 UTC||Need Help??|
I'm confident that the basic close-on-exec mechanism of $^F works on all Unix platforms because I remember writing a test for it, t/run/cloexec.t, which should be run when Perl is built. Did you build Perl from source and, if so, did the cloexec.t test pass? Which Perl version are you using and which OS? Are you able to run the cloexec.t test on your Perl?
In any case, even if you didn't explicitly set $^F, I expect the socket fd would be greater than two and so should be closed across an exec for the default value of $^F (see perlvar for details on $^F close-on-exec behaviour).
BTW, you can see how close-on-exec is implemented by searching for close-on-exec in the Perl C sources, for example from pp_sys.c:
How well this works on all Unices and in all environments, I cannot be certain of. For example, Linux open call cautions:
Additionally, use of this flag is essential in some multithreaded programs since using a separate fcntl(2) F_SETFD operation to set the FD_CLOEXEC flag does not suffice to avoid race conditions where one thread opens a file descriptor at the same time as another thread does a fork(2) plus execve(2).
Moreover, calling close on a socket closes your program's interface to the socket not the socket itself. It is up to the kernel to close the socket and it may be kept alive for a few minutes after you close it (see unix socket faq).
It is going to be tricky to figure out what is going on. A tool like lsof would be especially useful. Perhaps strace too. Along with a very small test program to investigate what is going on.