diff --git a/ChangeLog b/ChangeLog index c80795ba04..9700fefcf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Thu Jul 24 16:30:21 2008 NAKAMURA Usaku + + * win32/win32.c (exit_handler): use st_free_table() to free socklist. + + * win32/win32.c (rb_w32_pipe_exec, rb_w32_accept, rb_w32_socket, + rb_w32_socketpair): should check and release fd and sockets/handles + if an error occurs in rb_w32_open_osfhandle(). + Thu Jul 24 16:05:02 2008 NAKAMURA Usaku * win32/win32.c (overlapped_socket_io): avoid warnings. diff --git a/win32/win32.c b/win32/win32.c index f71a56a0de..f6233e4bf3 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -439,7 +439,7 @@ exit_handler(void) { if (NtSocketsInitialized) { WSACleanup(); - xfree(socklist); + st_free_table(socklist); socklist = NULL; NtSocketsInitialized = 0; } @@ -751,10 +751,9 @@ rb_w32_join_argv(char *cmd, char *const *argv) return cmd; } -static int socketpair_internal(int af, int type, int protocol, SOCKET *sv); - rb_pid_t -rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, int *write_pipe) +rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, + int *write_pipe) { struct ChildRecord* child; HANDLE hIn, hOut; @@ -762,7 +761,6 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, int *wr HANDLE hCurProc; SECURITY_ATTRIBUTES sa; BOOL reading, writing; - int binmode; int ret; /* Figure out what we're doing... */ @@ -777,7 +775,9 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, int *wr reading = TRUE; writing = FALSE; } - binmode |= (mode & O_BINARY) ? O_BINARY : O_TEXT; + mode &= ~(O_RDWR|O_RDONLY|O_WRONLY); + if (!(mode & O_BINARY)) + mode |= O_TEXT; sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; @@ -837,21 +837,31 @@ rb_w32_pipe_exec(const char *cmd, const char *prog, int mode, int *pipe, int *wr /* associate handle to file descritor */ if (reading) { - *pipe = rb_w32_open_osfhandle((intptr_t)hDupIn, _O_RDONLY | binmode); + *pipe = rb_w32_open_osfhandle((intptr_t)hDupIn, O_RDONLY | mode); if (writing) - *write_pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, _O_WRONLY | binmode); + *write_pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, + O_WRONLY | mode); } else { - *pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, _O_WRONLY | binmode); + *pipe = rb_w32_open_osfhandle((intptr_t)hDupOut, O_WRONLY | mode); } if (hIn) CloseHandle(hIn); if (hOut) CloseHandle(hOut); - if (*pipe == -1) { - if (hDupIn) + if (reading && writing && *write_pipe == -1) { + if (*pipe != -1) + rb_w32_close(*pipe); + else CloseHandle(hDupIn); - if (hDupOut) + CloseHandle(hDupOut); + CloseChildHandle(child); + break; + } + else if (*pipe == -1) { + if (reading) + CloseHandle(hDupIn); + else CloseHandle(hDupOut); CloseChildHandle(child); break; @@ -2272,8 +2282,11 @@ rb_w32_accept(int s, struct sockaddr *addr, int *addrlen) s = -1; } else { - st_insert(socklist, (st_data_t)r, (st_data_t)0); s = rb_w32_open_osfhandle(r, O_RDWR|O_BINARY|O_NOINHERIT); + if (s != -1) + st_insert(socklist, (st_data_t)r, (st_data_t)0); + else + closesocket(r); } }); return s; @@ -2629,8 +2642,11 @@ rb_w32_socket(int af, int type, int protocol) fd = -1; } else { - st_insert(socklist, (st_data_t)s, (st_data_t)0); fd = rb_w32_open_osfhandle(s, O_RDWR|O_BINARY|O_NOINHERIT); + if (fd != -1) + st_insert(socklist, (st_data_t)s, (st_data_t)0); + else + closesocket(s); } }); return fd; @@ -2850,10 +2866,20 @@ rb_w32_socketpair(int af, int type, int protocol, int *sv) if (socketpair_internal(af, type, protocol, pair) < 0) return -1; + sv[0] = rb_w32_open_osfhandle(pair[0], O_RDWR|O_BINARY|O_NOINHERIT); + if (sv[0] == -1) { + closesocket(pair[0]); + closesocket(pair[1]); + return -1; + } + sv[1] = rb_w32_open_osfhandle(pair[1], O_RDWR|O_BINARY|O_NOINHERIT); + if (sv[1] == -1) { + rb_w32_close(sv[0]); + closesocket(pair[1]); + return -1; + } st_insert(socklist, (st_data_t)pair[0], (st_data_t)0); st_insert(socklist, (st_data_t)pair[1], (st_data_t)0); - sv[0] = rb_w32_open_osfhandle(pair[0], O_RDWR|O_BINARY|O_NOINHERIT); - sv[1] = rb_w32_open_osfhandle(pair[1], O_RDWR|O_BINARY|O_NOINHERIT); return 0; }