Eric Blake wrote:
> > nfd = _open_osfhandle ((long) new_handle,
> > O_NOINHERIT | (flags & (O_TEXT | O_BINARY)));
> > if (nfd < 0)
> > {
> > int saved_errno = errno;
> > close (fd);
> > errno = saved_errno;
> > return -1;
> > }
> >
> > close (fd);
> > return nfd;
>
> This means that nfd > fd, so there is a gap in the fd sequence which is
> unexpected per POSIX rules. Is it worth the hassle of using
> dup2(nfd,fd),close(fd) instead of close(fd)?
Good point. This gap can be avoided like this:
if (flags & SOCK_CLOEXEC)
{
HANDLE curr_process = GetCurrentProcess ();
HANDLE old_handle = (HANDLE) _get_osfhandle (fd);
HANDLE new_handle;
if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
old_handle, /* SourceHandle */
curr_process, /* TargetProcessHandle */
(PHANDLE) &new_handle, /* TargetHandle */
(DWORD) 0, /* DesiredAccess */
FALSE, /* InheritHandle */
DUPLICATE_SAME_ACCESS)) /* Options */
{
close (fd);
errno = EBADF; /* arbitrary */
return -1;
}
/* Closing fd before allocating the new fd ensures that the new fd will
have the minimum possible value. */
close (fd);
return _open_osfhandle ((long) new_handle,
O_NOINHERIT | (flags & (O_TEXT | O_BINARY)));
}
> > if (flags & SOCK_CLOEXEC)
> > {
> > int fcntl_flags;
> >
> > if ((fcntl_flags = fcntl (fd, F_GETFD, 0)) < 0
> > || fcntl (fd, F_SETFD, fcntl_flags | FD_CLOEXEC) < 0)
>
> Success for F_SETFD is like F_SETFL - you must compare against explicit -1.
Done.
> Do you have a test case in mind?
Not on this one. It's expensive to write a test for this one.
Bruno