Eric Blake wrote: > Calling close(fileno(fp)) prior to fclose(fp) is racy in a > multi-threaded application - some other thread could open a new file, > which is then inadvertently closed by the fclose that we thought > should fail with EBADF. For mingw, this is no worse than the race > already present in close_fd_maybe_socket for calling closesocket() > prior to _close(), but for all other platforms, we might as well be > nice and avoid the race. > > * lib/fclose.c (rpl_fclose): Rewrite to avoid double-close race on > all but WINDOWS_SOCKETS.
Good one. > This patch is necessary to avoid a regression on libvirt on Linux. Note to readers (I know Eric knows): the fclose replacement is necessary because of a POSIX-noncompliance bug present even in the very latest glibc. http://sources.redhat.com/bugzilla/show_bug.cgi?id=12724 > Is it worth thinking about replacing _every_ standard function on > mingw that can possibly create an fd in another thread (obviously, > as an optional module, only needed in multithreaded gnulib clients), > by grabbing a mutex to thus guarantee atomicity around otherwise > racy operations like the one in our fclose() wrapper? Or do we > just chalk up the race to the poor quality of mingw in the first > place, since more compliant platforms don't have the race, and since > the cost of replacing everything just to guarantee atomicity sounds > like it would significantly slow down mingw execution. If it's worth worrying about, the latter (below) sounds better. > Or do we come up with some alternative on mingw that avoids the > race? Perhaps opening a temporary fd on /dev/null, then using > dup2 to overwrite the fd underlying the file pointer after the > fflush(), so that we can then use fclose() and expect success > (since fclose is no longer operating on a socket fd) while still > gracefully closing out the socket? For that matter, does dup2() > on mingw properly handle the case where the destination fd is > an open socket?