-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Eric Blake on 8/19/2009 11:06 AM: > I went ahead and implemented popen_safer.
And this patch also includes a first use of O_CLOEXEC; I'm debating about adding more O_CLOEXEC support throughout gnulib, a piece at a time. cloexec support has two benefits - fewer syscalls on newer kernels, and multithread safety (closing the window where a second thread can do a fork/exec and leak an fd during the window of the first thread doing fd creation and fcntl). Without atomic cloexec support from the kernel, we can't avoid the race (short of wrapping a mutex around every call to any function that might create an fd, including library functions that might temporarily open an fd under the hood); but most gnulib clients are single-threaded and would at least benefit from a speedup due to fewer kernel calls. Thoughts before I start tackling this? cloexec - convenience wrapper - On mingw, there is no fcntl or FD_CLOEXEC, however, the primary semantics of FD_CLOEXEC (making an fd invisible to exec'd child processes) maps very well to win32 O_NOINHERIT. w32spawn.h has dup_noinherit that tweaks the O_NOINHERIT flag, but we also need to tweak the O_NOINHERIT flag of an existing fd without having to use dup in cloexec.c (I'm hoping the windows functions GetHandleInformation and SetHandleInformation work here). And since fcntl is not portable, it would be nice to add this convenience prototype to cloexec.h: /* Return true if FD will not be inherited into child processes. */ bool get_cloexec_flag (int fd); open - Required by POSIX 2008 - We can't support atomic O_CLOEXEC if the OS doesn't obey POSIX 2008, but we can at least fake it. But not all programs will be using O_CLOEXEC, so it seems like it is best to add a new module open-cloexec, and only add O_CLOEXEC support if the module is requested rather than blindly wrap open. Implementation is simple - if O_CLOEXEC is requested but the OS doesn't support it, then call set_cloexec_handle after the fact in rpl_open. pipe2, dup3, accept4, mkostemp - GNU/Linux extensions - New modules to match recent glibc extensions around the recently added syscalls on Linux for passing O_CLOEXEC (or O_NONBLOCK) via the flag argument. Like open, we can't support atomic cloexec fd creation, but can use set_cloexec_handle as appropriate. Any other fd creation functions I'm forgetting? fcntl - required by POSIX 2008 - we still don't support all of the F_* flags required by POSIX, and mingw doesn't have an fcntl to wrap, so implementing a complete fcntl is daunting. But maybe we could make a new module fcntl-dupfd that handles just F_DUPFD and F_DUPFD_CLOEXEC on mingw, and adds non-atomic F_DUPFD_CLOEXEC for all remaining lacking platforms. Should we do this via the name rpl_fcntl, or wrap it in a named API more like cloexec's set_cloexec_flag? Also, on mingw, I know of no way to open the first free fd after a given point (the only arbitrary opening point is via dup2, but that clobbers any existing fd), so we'd either have to loop from the target until we find a free fd, or temporarily tie up all free fds lower than the target (neither of which sounds thread-safe, but then again I didn't promise atomic operation). accept, pipe, dup2, mkstemp - no way to pass flag information, hence the glibc extensions accept4, pipe2, dup3, mkostemp fopen, fdopen, freopen, popen - glibc extensions - glibc recognizes 'e' in the mode argument to stdio functions offers fopen (file, "re") as a shortcut to use O_CLOEXEC under the hood. Can be implemented with a wrapper that filters the mode before calling the original function, then calls set_cloexec_flag as appropriate. Other flags like 'x' for O_EXCL could also be implemented for fopen (using open/fdopen instead of wrapping fopen). Any other stream creation functions I'm forgetting? opendir - no way to pass flags, but the fd is already treated as cloexec per POSIX rules (whether or not it is actually marked cloexec); no changes needed. Are there any OS's out there that disobey POSIX and leak an open directory fd into child processes? tmpfile - no way to pass flag information. Is there any glibc analog to tmpfile that takes flags? Meanwhile, we have the gnulib module clean-tmp, but open_temp and fopen_temp should be able to use the same flags as open and fopen, so it seems like no changes are needed on that front anything else? - -- Don't work too hard, make some time for fun as well! Eric Blake [email protected] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkqMQEwACgkQ84KuGfSFAYDPnQCbBI4+ouu9dm6mR4Iam43T4uCK oiYAn3LBo7DhsCA7yAOiklyMBzrMbpJe =8+Ep -----END PGP SIGNATURE-----
