1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* win32/win32.c (setfl): extract from fcntl().

* win32/win32.c (dupfd): new function to support F_DUPFD. base on a
  patch written by akr.

* win32/win32.c (fcntl): use above functions.

* include/ruby/win32.h (F_DUPFD): define. [experimental]

* include/ruby/win32.h (F_SETFL): change the value to correspond with
  other platforms.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33581 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2011-10-31 04:16:11 +00:00
parent 92a8bfacd9
commit b2a1af1547
3 changed files with 98 additions and 18 deletions

View file

@ -1,3 +1,17 @@
Mon Oct 31 13:10:06 2011 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.c (setfl): extract from fcntl().
* win32/win32.c (dupfd): new function to support F_DUPFD. base on a
patch written by akr.
* win32/win32.c (fcntl): use above functions.
* include/ruby/win32.h (F_DUPFD): define. [experimental]
* include/ruby/win32.h (F_SETFL): change the value to correspond with
other platforms.
Mon Oct 31 12:37:50 2011 Tanaka Akira <akr@fsij.org> Mon Oct 31 12:37:50 2011 Tanaka Akira <akr@fsij.org>
* ext/pty/pty.c (get_device_once): use O_CLOEXEC for posix_openpt if * ext/pty/pty.c (get_device_once): use O_CLOEXEC for posix_openpt if

View file

@ -569,7 +569,12 @@ extern char *rb_w32_strerror(int);
# define EREMOTE WSAEREMOTE # define EREMOTE WSAEREMOTE
#endif #endif
#define F_SETFL 1 #define F_DUPFD 0
//#define F_GETFD 1
//#define F_SETFD 2
//#define F_GETFL 3
#define F_SETFL 4
//#define FD_CLOEXEC 1 /* F_GETFD, F_SETFD */
#define O_NONBLOCK 1 #define O_NONBLOCK 1
#undef FD_SET #undef FD_SET

View file

@ -3766,28 +3766,13 @@ void setprotoent (int stayopen) {}
void setservent (int stayopen) {} void setservent (int stayopen) {}
/* License: Ruby's */ /* License: Ruby's */
int static int
fcntl(int fd, int cmd, ...) setfl(SOCKET sock, int arg)
{ {
SOCKET sock = TO_SOCKET(fd);
va_list va;
int arg;
int ret; int ret;
int flag = 0; int flag = 0;
u_long ioctlArg; u_long ioctlArg;
if (!is_socket(sock)) {
errno = EBADF;
return -1;
}
if (cmd != F_SETFL) {
errno = EINVAL;
return -1;
}
va_start(va, cmd);
arg = va_arg(va, int);
va_end(va);
socklist_lookup(sock, &flag); socklist_lookup(sock, &flag);
if (arg & O_NONBLOCK) { if (arg & O_NONBLOCK) {
flag |= O_NONBLOCK; flag |= O_NONBLOCK;
@ -3808,6 +3793,82 @@ fcntl(int fd, int cmd, ...)
return ret; return ret;
} }
/* License: Ruby's */
static int
dupfd(HANDLE hDup, char flags, int minfd)
{
int save_errno;
int ret;
int fds[32];
int filled = 0;
do {
ret = _open_osfhandle((intptr_t)hDup, flags | FOPEN);
if (ret == -1) {
goto close_fds_and_return;
}
if (ret >= minfd) {
goto close_fds_and_return;
}
fds[filled++] = ret;
} while (filled < (sizeof(fds)/sizeof(fds[0])));
ret = dupfd(hDup, flags, minfd);
close_fds_and_return:
save_errno = errno;
while (filled > 0) {
_osfhnd(fds[--filled]) = (intptr_t)INVALID_HANDLE_VALUE;
close(fds[filled]);
}
errno = save_errno;
return ret;
}
/* License: Ruby's */
int
fcntl(int fd, int cmd, ...)
{
va_list va;
int arg;
if (cmd == F_SETFL) {
SOCKET sock = TO_SOCKET(fd);
if (!is_socket(sock)) {
errno = EBADF;
return -1;
}
va_start(va, cmd);
arg = va_arg(va, int);
va_end(va);
return setfl(sock, arg);
}
else if (cmd == F_DUPFD) {
int ret;
HANDLE hDup;
if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
GetCurrentProcess(), &hDup, 0L, TRUE,
DUPLICATE_SAME_ACCESS))) {
errno = map_errno(GetLastError());
return -1;
}
va_start(va, cmd);
arg = va_arg(va, int);
va_end(va);
if ((ret = dupfd(hDup, _osfile(fd), arg)) == -1)
CloseHandle(hDup);
return ret;
}
else {
errno = EINVAL;
return -1;
}
}
#ifndef WNOHANG #ifndef WNOHANG
#define WNOHANG -1 #define WNOHANG -1
#endif #endif