aboutsummaryrefslogtreecommitdiffstats
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
parent78f7e342d156ee139aec307225e7c37e17cef1ff (diff)
downloadruby-f150a381db5b51552b714e9a5893654cd056962c.tar.gz
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
-rw-r--r--ChangeLog5
-rw-r--r--include/ruby/win32.h5
-rw-r--r--test/ruby/test_process.rb2
-rw-r--r--win32/win32.c47
4 files changed, 48 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 21f8d0efd5..f32bd51d0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Sep 12 14:23:20 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * win32/win32.c (fcntl): implement F_GETFD, F_SETFD, and
+ F_DUPFD_CLOEXEC.
+
Sat Sep 12 05:35:24 2015 Eric Wong <e@80x24.org>
* rational.c (string_to_r_strict): preserve encoding in exception
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index 0d07745eda..c26aa9d4f9 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -577,15 +577,14 @@ extern char *rb_w32_strerror(int);
#endif
#define F_DUPFD 0
-#if 0
#define F_GETFD 1
#define F_SETFD 2
+#if 0
#define F_GETFL 3
#endif
#define F_SETFL 4
-#if 0
+#define F_DUPFD_CLOEXEC 67
#define FD_CLOEXEC 1 /* F_GETFD, F_SETFD */
-#endif
#define O_NONBLOCK 1
#undef FD_SET
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index e26d0a46a5..32dcaed144 100644
--- a/test/ruby/test_process.rb
+++ b/test/ruby/test_process.rb
@@ -970,7 +970,7 @@ class TestProcess < Test::Unit::TestCase
rescue NotImplementedError
skip "IO#close_on_exec= is not supported"
end
- end
+ end unless windows? # passing non-stdio fds is not supported on Windows
def test_execopts_redirect_tempfile
bug6269 = '[ruby-core:44181]'
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;
}