From f150a381db5b51552b714e9a5893654cd056962c Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 12 Sep 2015 05:23:22 +0000 Subject: win32.c: more fcntl * win32/win32.c (fcntl): implement F_GETFD, F_SETFD, and F_DUPFD_CLOEXEC. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/win32.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'win32/win32.c') diff --git a/win32/win32.c b/win32/win32.c index d1cfb6bcf5..11292a16cc 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -4144,8 +4144,10 @@ fcntl(int fd, int cmd, ...) { va_list va; int arg; + DWORD flag; - if (cmd == F_SETFL) { + switch (cmd) { + case F_SETFL: { SOCKET sock = TO_SOCKET(fd); if (!is_socket(sock)) { errno = EBADF; @@ -4156,13 +4158,14 @@ fcntl(int fd, int cmd, ...) arg = va_arg(va, int); va_end(va); return setfl(sock, arg); - } - else if (cmd == F_DUPFD) { + } + case F_DUPFD: case F_DUPFD_CLOEXEC: { int ret; HANDLE hDup; + flag = _osfile(fd); if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd), GetCurrentProcess(), &hDup, 0L, - !(_osfile(fd) & FNOINHERIT), + cmd == F_DUPFD && !(flag & FNOINHERIT), DUPLICATE_SAME_ACCESS))) { errno = map_errno(GetLastError()); return -1; @@ -4172,11 +4175,41 @@ fcntl(int fd, int cmd, ...) arg = va_arg(va, int); va_end(va); - if ((ret = dupfd(hDup, _osfile(fd), arg)) == -1) + if (cmd != F_DUPFD) + flag |= FNOINHERIT; + else + flag &= ~FNOINHERIT; + if ((ret = dupfd(hDup, flag, arg)) == -1) CloseHandle(hDup); return ret; - } - else { + } + case F_GETFD: { + SIGNED_VALUE h = _get_osfhandle(fd); + if (h == -1) return -1; + if (!GetHandleInformation((HANDLE)h, &flag)) { + errno = map_errno(GetLastError()); + return -1; + } + return (flag & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC; + } + case F_SETFD: { + SIGNED_VALUE h = _get_osfhandle(fd); + if (h == -1) return -1; + va_start(va, cmd); + arg = va_arg(va, int); + va_end(va); + if (!SetHandleInformation((HANDLE)h, HANDLE_FLAG_INHERIT, + (arg & FD_CLOEXEC) ? 0 : HANDLE_FLAG_INHERIT)) { + errno = map_errno(GetLastError()); + return -1; + } + if (arg & FD_CLOEXEC) + _osfile(fd) |= FNOINHERIT; + else + _osfile(fd) &= ~FNOINHERIT; + return 0; + } + default: errno = EINVAL; return -1; } -- cgit v1.2.3