From 0c5f365327f7d6f157612ffb32f2c5321cfe6872 Mon Sep 17 00:00:00 2001 From: usa Date: Thu, 24 Jul 2008 07:33:00 +0000 Subject: * 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(). git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@18196 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/win32.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'win32') diff --git a/win32/win32.c b/win32/win32.c index f71a56a0d..f6233e4bf 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; - 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); + 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); return 0; } -- cgit