* 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>
* rational.c (string_to_r_strict): preserve encoding in exception

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

@ -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

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

@ -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]'

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

@ -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;
}