diff --git a/ChangeLog b/ChangeLog index fa0c04c477..6ee9d1c997 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Mon Dec 6 20:13:28 2004 NAKAMURA Usaku + + * 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 * Makefile.in (.y.c): simplify the rule. diff --git a/io.c b/io.c index beaf102611..4edae54176 100644 --- a/io.c +++ b/io.c @@ -20,7 +20,13 @@ #include #include -#include +#if !defined(_WIN32) +# if defined(__BEOS__) +# include +# else +# include +# endif +#endif #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(_WIN32) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__) # define NO_SAFE_RENAME @@ -131,6 +137,19 @@ static VALUE lineno = INT2FIX(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 rb_eof_error() { @@ -1940,7 +1959,8 @@ rb_io_fptr_finalize(fptr) free(fptr->path); fptr->path = 0; } - rb_io_fptr_cleanup(fptr, Qtrue); + if (fptr->f) + rb_io_fptr_cleanup(fptr, Qtrue); if (fptr->rbuf) { free(fptr->rbuf); fptr->rbuf = 0; @@ -2059,15 +2079,12 @@ rb_io_close_read(io) VALUE io; { OpenFile *fptr; - struct stat sbuf; if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { rb_raise(rb_eSecurityError, "Insecure: can't close"); } GetOpenFile(io, fptr); - if (fstat(fptr->fd, &sbuf) < 0) - rb_sys_fail(fptr->path); - if (S_ISSOCK(sbuf.st_mode)) { + if (is_socket(fptr->fd)) { if (shutdown(fptr->fd, 0) < 0) rb_sys_fail(fptr->path); fptr->mode &= ~FMODE_READABLE; @@ -2105,15 +2122,12 @@ rb_io_close_write(io) VALUE io; { OpenFile *fptr; - struct stat sbuf; if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) { rb_raise(rb_eSecurityError, "Insecure: can't close"); } GetOpenFile(io, fptr); - if (fstat(fptr->fd, &sbuf) < 0) - rb_sys_fail(fptr->path); - if (S_ISSOCK(sbuf.st_mode)) { + if (is_socket(fptr->fd)) { if (shutdown(fptr->fd, 1) < 0) rb_sys_fail(fptr->path); fptr->mode &= ~FMODE_WRITABLE; @@ -2790,7 +2804,7 @@ pipe_open(argc, argv, mode) struct popen_arg arg; volatile int doexec; #elif defined(_WIN32) - FILE *fpr, *fpw; + int r, w; int openmode = rb_io_mode_modenum(mode); char *exename = NULL; #endif @@ -2880,7 +2894,7 @@ pipe_open(argc, argv, mode) else { 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 */ switch (errno) { case EAGAIN: @@ -2894,7 +2908,16 @@ pipe_open(argc, argv, mode) 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 prog = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); fp = popen(StringValueCStr(prog), mode); diff --git a/win32/win32.c b/win32/win32.c index ed6402cc62..6dc8fffe4e 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -675,7 +675,7 @@ rb_w32_join_argv(char *cmd, char *const *argv) pid_t rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, - FILE **fpr, FILE **fpw) + int *pr, int *pw) { struct ChildRecord* child; HANDLE hReadIn, hReadOut; @@ -687,7 +687,6 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, BOOL reading, writing; int fd; int pipemode; - char modes[3]; int ret; /* 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; if (mode & O_BINARY) { pipemode = O_BINARY; - modes[1] = 'b'; - modes[2] = '\0'; } else { pipemode = O_TEXT; - modes[1] = '\0'; } 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 */ if (reading) { - fd = rb_w32_open_osfhandle((long)hDupInFile, - (_O_RDONLY | pipemode)); + *pr = rb_w32_open_osfhandle((long)hDupInFile, + (_O_RDONLY | pipemode)); CloseHandle(hReadOut); - if (fd == -1) { + if (*pr == -1) { CloseHandle(hDupInFile); read_open_failed: if (writing) { @@ -780,30 +776,20 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, CloseChildHandle(child); break; } - modes[0] = 'r'; - if ((*fpr = (FILE *)fdopen(fd, modes)) == NULL) { - _close(fd); - goto read_open_failed; - } } if (writing) { - fd = rb_w32_open_osfhandle((long)hDupOutFile, - (_O_WRONLY | pipemode)); + *pw = rb_w32_open_osfhandle((long)hDupOutFile, + (_O_WRONLY | pipemode)); CloseHandle(hWriteIn); - if (fd == -1) { + if (*pw == -1) { CloseHandle(hDupOutFile); write_open_failed: if (reading) { - fclose(*fpr); + close(*pr); } CloseChildHandle(child); break; } - modes[0] = 'w'; - if ((*fpw = (FILE *)fdopen(fd, modes)) == NULL) { - _close(fd); - goto write_open_failed; - } } ret = child->pid; } while (0)); @@ -1672,8 +1658,14 @@ rb_w32_open_osfhandle(long osfhandle, int flags) #undef getsockopt +int +rb_w32_is_socket(int fd) +{ + return is_socket(TO_SOCKET(fd)); +} + static int -is_socket(SOCKET fd) +is_socket(SOCKET sock) { char sockbuf[80]; int optlen; @@ -1682,7 +1674,7 @@ is_socket(SOCKET fd) optlen = sizeof(sockbuf); RUBY_CRITICAL({ - retval = getsockopt(fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); + retval = getsockopt(sock, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); if (retval == SOCKET_ERROR) { int iRet; 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; diff --git a/win32/win32.h b/win32/win32.h index 16acd1c955..4ca3b299bc 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -138,8 +138,9 @@ struct timezone { #endif extern void NtInitialize(int *, 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 rb_w32_is_socket(int); extern int rb_w32_accept(int, struct sockaddr *, int *); extern int rb_w32_bind(int, struct sockaddr *, int); extern int rb_w32_connect(int, struct sockaddr *, int);