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
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:
#if defined(HAS_FCNTL) && defined(F_SETFD)
fcntl(fd, F_SETFD, fd > PL_maxsysfd); /* ensure close-on-exe
How well this works on all Unices and in all environments,
I cannot be certain of.
For example, Linux open
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.
Update: as a workaround, instead of calling system,
you could try calling fork,
then explicitly close the socket, then call exec.