summaryrefslogtreecommitdiff
path: root/win32/win32.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-12 05:23:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-09-12 05:23:22 +0000
commitf150a381db5b51552b714e9a5893654cd056962c (patch)
tree54c9c3ef3676f32b26ddb8a7b56eda1e6fdf4cb5 /win32/win32.c
parent78f7e342d156ee139aec307225e7c37e17cef1ff (diff)
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
Diffstat (limited to 'win32/win32.c')
-rw-r--r--win32/win32.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/win32/win32.c b/win32/win32.c
index d1cfb6b..11292a1 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;
}