* 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
This commit is contained in:
nobu 2015-09-12 05:23:22 +00:00
Родитель 78f7e342d1
Коммит f150a381db
4 изменённых файлов: 48 добавлений и 11 удалений

Просмотреть файл

@ -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> Sat Sep 12 05:35:24 2015 Eric Wong <e@80x24.org>
* rational.c (string_to_r_strict): preserve encoding in exception * rational.c (string_to_r_strict): preserve encoding in exception

Просмотреть файл

@ -577,15 +577,14 @@ extern char *rb_w32_strerror(int);
#endif #endif
#define F_DUPFD 0 #define F_DUPFD 0
#if 0
#define F_GETFD 1 #define F_GETFD 1
#define F_SETFD 2 #define F_SETFD 2
#if 0
#define F_GETFL 3 #define F_GETFL 3
#endif #endif
#define F_SETFL 4 #define F_SETFL 4
#if 0 #define F_DUPFD_CLOEXEC 67
#define FD_CLOEXEC 1 /* F_GETFD, F_SETFD */ #define FD_CLOEXEC 1 /* F_GETFD, F_SETFD */
#endif
#define O_NONBLOCK 1 #define O_NONBLOCK 1
#undef FD_SET #undef FD_SET

Просмотреть файл

@ -970,7 +970,7 @@ class TestProcess < Test::Unit::TestCase
rescue NotImplementedError rescue NotImplementedError
skip "IO#close_on_exec= is not supported" skip "IO#close_on_exec= is not supported"
end end
end end unless windows? # passing non-stdio fds is not supported on Windows
def test_execopts_redirect_tempfile def test_execopts_redirect_tempfile
bug6269 = '[ruby-core:44181]' bug6269 = '[ruby-core:44181]'

Просмотреть файл

@ -4144,8 +4144,10 @@ fcntl(int fd, int cmd, ...)
{ {
va_list va; va_list va;
int arg; int arg;
DWORD flag;
if (cmd == F_SETFL) { switch (cmd) {
case F_SETFL: {
SOCKET sock = TO_SOCKET(fd); SOCKET sock = TO_SOCKET(fd);
if (!is_socket(sock)) { if (!is_socket(sock)) {
errno = EBADF; errno = EBADF;
@ -4156,13 +4158,14 @@ fcntl(int fd, int cmd, ...)
arg = va_arg(va, int); arg = va_arg(va, int);
va_end(va); va_end(va);
return setfl(sock, arg); return setfl(sock, arg);
} }
else if (cmd == F_DUPFD) { case F_DUPFD: case F_DUPFD_CLOEXEC: {
int ret; int ret;
HANDLE hDup; HANDLE hDup;
flag = _osfile(fd);
if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd), if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
GetCurrentProcess(), &hDup, 0L, GetCurrentProcess(), &hDup, 0L,
!(_osfile(fd) & FNOINHERIT), cmd == F_DUPFD && !(flag & FNOINHERIT),
DUPLICATE_SAME_ACCESS))) { DUPLICATE_SAME_ACCESS))) {
errno = map_errno(GetLastError()); errno = map_errno(GetLastError());
return -1; return -1;
@ -4172,11 +4175,41 @@ fcntl(int fd, int cmd, ...)
arg = va_arg(va, int); arg = va_arg(va, int);
va_end(va); 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); CloseHandle(hDup);
return ret; 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; errno = EINVAL;
return -1; return -1;
} }