зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
78f7e342d1
Коммит
f150a381db
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче