* io.c (is_socket): new function.

* io.c (rb_io_close_read, rb_io_close_write): use is_socket().

* io.c (rb_io_fptr_finalize): need to check fptr->f before calling
  rb_io_fptr_cleanup().

* io.c (pipe_open): win32 pipe support (experimental).

* win32/win32.[ch] (rb_w32_pipe_exec): return file descripters
  instead of FILE structure.

* win32/win32.[ch] (rb_w32_is_socket): new function.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2004-12-06 11:19:27 +00:00
Родитель 3bd61a71a0
Коммит 1acf7e6b01
4 изменённых файлов: 71 добавлений и 39 удалений

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

@ -1,3 +1,19 @@
Mon Dec 6 20:13:28 2004 NAKAMURA Usaku <usa@ruby-lang.org>
* io.c (is_socket): new function.
* io.c (rb_io_close_read, rb_io_close_write): use is_socket().
* io.c (rb_io_fptr_finalize): need to check fptr->f before calling
rb_io_fptr_cleanup().
* io.c (pipe_open): win32 pipe support (experimental).
* win32/win32.[ch] (rb_w32_pipe_exec): return file descripters
instead of FILE structure.
* win32/win32.[ch] (rb_w32_is_socket): new function.
Mon Dec 6 19:40:40 2004 WATANABE Hirofumi <eban@ruby-lang.org> Mon Dec 6 19:40:40 2004 WATANABE Hirofumi <eban@ruby-lang.org>
* Makefile.in (.y.c): simplify the rule. * Makefile.in (.y.c): simplify the rule.

49
io.c
Просмотреть файл

@ -20,7 +20,13 @@
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #if !defined(_WIN32)
# if defined(__BEOS__)
# include <net/socket.h>
# else
# include <sys/socket.h>
# endif
#endif
#if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__) #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__)
# define NO_SAFE_RENAME # define NO_SAFE_RENAME
@ -131,6 +137,19 @@ static VALUE lineno = INT2FIX(0);
}\ }\
} while(0) } while(0)
#if defined(_WIN32)
#define is_socket(fd) rb_w32_is_socket(fd)
#else
static int
is_socket(fd)
int fd;
{
if (fstat(fptr->fd, &sbuf) < 0)
rb_sys_fail(fptr->path);
return S_ISSOCK(sbuf.st_mode);
}
#endif
void void
rb_eof_error() rb_eof_error()
{ {
@ -1940,7 +1959,8 @@ rb_io_fptr_finalize(fptr)
free(fptr->path); free(fptr->path);
fptr->path = 0; fptr->path = 0;
} }
rb_io_fptr_cleanup(fptr, Qtrue); if (fptr->f)
rb_io_fptr_cleanup(fptr, Qtrue);
if (fptr->rbuf) { if (fptr->rbuf) {
free(fptr->rbuf); free(fptr->rbuf);
fptr->rbuf = 0; fptr->rbuf = 0;
@ -2059,15 +2079,12 @@ rb_io_close_read(io)
VALUE io; VALUE io;
{ {
OpenFile *fptr; OpenFile *fptr;
struct stat sbuf;
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
rb_raise(rb_eSecurityError, "Insecure: can't close"); rb_raise(rb_eSecurityError, "Insecure: can't close");
} }
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
if (fstat(fptr->fd, &sbuf) < 0) if (is_socket(fptr->fd)) {
rb_sys_fail(fptr->path);
if (S_ISSOCK(sbuf.st_mode)) {
if (shutdown(fptr->fd, 0) < 0) if (shutdown(fptr->fd, 0) < 0)
rb_sys_fail(fptr->path); rb_sys_fail(fptr->path);
fptr->mode &= ~FMODE_READABLE; fptr->mode &= ~FMODE_READABLE;
@ -2105,15 +2122,12 @@ rb_io_close_write(io)
VALUE io; VALUE io;
{ {
OpenFile *fptr; OpenFile *fptr;
struct stat sbuf;
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
rb_raise(rb_eSecurityError, "Insecure: can't close"); rb_raise(rb_eSecurityError, "Insecure: can't close");
} }
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
if (fstat(fptr->fd, &sbuf) < 0) if (is_socket(fptr->fd)) {
rb_sys_fail(fptr->path);
if (S_ISSOCK(sbuf.st_mode)) {
if (shutdown(fptr->fd, 1) < 0) if (shutdown(fptr->fd, 1) < 0)
rb_sys_fail(fptr->path); rb_sys_fail(fptr->path);
fptr->mode &= ~FMODE_WRITABLE; fptr->mode &= ~FMODE_WRITABLE;
@ -2790,7 +2804,7 @@ pipe_open(argc, argv, mode)
struct popen_arg arg; struct popen_arg arg;
volatile int doexec; volatile int doexec;
#elif defined(_WIN32) #elif defined(_WIN32)
FILE *fpr, *fpw; int r, w;
int openmode = rb_io_mode_modenum(mode); int openmode = rb_io_mode_modenum(mode);
char *exename = NULL; char *exename = NULL;
#endif #endif
@ -2880,7 +2894,7 @@ pipe_open(argc, argv, mode)
else { else {
cmd = StringValueCStr(prog); cmd = StringValueCStr(prog);
} }
while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &fpr, &fpw)) == -1) { while ((pid = rb_w32_pipe_exec(cmd, exename, openmode, &r, &w)) == -1) {
/* exec failed */ /* exec failed */
switch (errno) { switch (errno) {
case EAGAIN: case EAGAIN:
@ -2894,7 +2908,16 @@ pipe_open(argc, argv, mode)
break; break;
} }
} }
#define PIPE_FDOPEN(i) (i?fpw:fpr) if ((modef & FMODE_READABLE) && (modef & FMODE_WRITABLE)) {
close(w);
fp = rb_fdopen(r, "r+");
}
else if (modef & FMODE_READABLE) {
fp = rb_fdopen(r, "r");
}
else {
fp = rb_fdopen(w, "w");
}
#else #else
prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" "));
fp = popen(StringValueCStr(prog), mode); fp = popen(StringValueCStr(prog), mode);

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

@ -675,7 +675,7 @@ rb_w32_join_argv(char *cmd, char *const *argv)
pid_t pid_t
rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, rb_w32_pipe_exec(const char *cmd, const char *prog, int mode,
FILE **fpr, FILE **fpw) int *pr, int *pw)
{ {
struct ChildRecord* child; struct ChildRecord* child;
HANDLE hReadIn, hReadOut; HANDLE hReadIn, hReadOut;
@ -687,7 +687,6 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode,
BOOL reading, writing; BOOL reading, writing;
int fd; int fd;
int pipemode; int pipemode;
char modes[3];
int ret; int ret;
/* Figure out what we're doing... */ /* Figure out what we're doing... */
@ -695,12 +694,9 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode,
reading = ((mode & O_RDWR) || !writing) ? TRUE : FALSE; reading = ((mode & O_RDWR) || !writing) ? TRUE : FALSE;
if (mode & O_BINARY) { if (mode & O_BINARY) {
pipemode = O_BINARY; pipemode = O_BINARY;
modes[1] = 'b';
modes[2] = '\0';
} }
else { else {
pipemode = O_TEXT; pipemode = O_TEXT;
modes[1] = '\0';
} }
sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.nLength = sizeof (SECURITY_ATTRIBUTES);
@ -767,10 +763,10 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode,
/* associate handle to fp */ /* associate handle to fp */
if (reading) { if (reading) {
fd = rb_w32_open_osfhandle((long)hDupInFile, *pr = rb_w32_open_osfhandle((long)hDupInFile,
(_O_RDONLY | pipemode)); (_O_RDONLY | pipemode));
CloseHandle(hReadOut); CloseHandle(hReadOut);
if (fd == -1) { if (*pr == -1) {
CloseHandle(hDupInFile); CloseHandle(hDupInFile);
read_open_failed: read_open_failed:
if (writing) { if (writing) {
@ -780,30 +776,20 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode,
CloseChildHandle(child); CloseChildHandle(child);
break; break;
} }
modes[0] = 'r';
if ((*fpr = (FILE *)fdopen(fd, modes)) == NULL) {
_close(fd);
goto read_open_failed;
}
} }
if (writing) { if (writing) {
fd = rb_w32_open_osfhandle((long)hDupOutFile, *pw = rb_w32_open_osfhandle((long)hDupOutFile,
(_O_WRONLY | pipemode)); (_O_WRONLY | pipemode));
CloseHandle(hWriteIn); CloseHandle(hWriteIn);
if (fd == -1) { if (*pw == -1) {
CloseHandle(hDupOutFile); CloseHandle(hDupOutFile);
write_open_failed: write_open_failed:
if (reading) { if (reading) {
fclose(*fpr); close(*pr);
} }
CloseChildHandle(child); CloseChildHandle(child);
break; break;
} }
modes[0] = 'w';
if ((*fpw = (FILE *)fdopen(fd, modes)) == NULL) {
_close(fd);
goto write_open_failed;
}
} }
ret = child->pid; ret = child->pid;
} while (0)); } while (0));
@ -1672,8 +1658,14 @@ rb_w32_open_osfhandle(long osfhandle, int flags)
#undef getsockopt #undef getsockopt
int
rb_w32_is_socket(int fd)
{
return is_socket(TO_SOCKET(fd));
}
static int static int
is_socket(SOCKET fd) is_socket(SOCKET sock)
{ {
char sockbuf[80]; char sockbuf[80];
int optlen; int optlen;
@ -1682,7 +1674,7 @@ is_socket(SOCKET fd)
optlen = sizeof(sockbuf); optlen = sizeof(sockbuf);
RUBY_CRITICAL({ RUBY_CRITICAL({
retval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); retval = getsockopt(sock, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
if (retval == SOCKET_ERROR) { if (retval == SOCKET_ERROR) {
int iRet; int iRet;
iRet = WSAGetLastError(); iRet = WSAGetLastError();
@ -1692,7 +1684,7 @@ is_socket(SOCKET fd)
}); });
// //
// If we get here, then fd is actually a socket. // If we get here, then sock is actually a socket.
// //
return result; return result;

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

@ -138,8 +138,9 @@ struct timezone {
#endif #endif
extern void NtInitialize(int *, char ***); extern void NtInitialize(int *, char ***);
extern int rb_w32_cmdvector(const char *, char ***); extern int rb_w32_cmdvector(const char *, char ***);
extern pid_t rb_w32_pipe_exec(const char *, const char *, int, FILE **, FILE **); extern pid_t rb_w32_pipe_exec(const char *, const char *, int, int *, int *);
extern int flock(int fd, int oper); extern int flock(int fd, int oper);
extern int rb_w32_is_socket(int);
extern int rb_w32_accept(int, struct sockaddr *, int *); extern int rb_w32_accept(int, struct sockaddr *, int *);
extern int rb_w32_bind(int, struct sockaddr *, int); extern int rb_w32_bind(int, struct sockaddr *, int);
extern int rb_w32_connect(int, struct sockaddr *, int); extern int rb_w32_connect(int, struct sockaddr *, int);