diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 276593926..d246e11a9 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2003-02-20 Corinna Vinschen + + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Check descriptor + created by cygheap_fdnew constructor. + * fhandler_virtual.cc (fhandler_virtual::opendir): Ditto. + * fhandler_socket.cc (fhandler_socket::accept): Ditto and move + creation of file descriptor behind blocking OS call. + * net.cc (cygwin_socket): Ditto. + (cygwin_rcmd): Ditto. + (cygwin_rresvport): Ditto. + (cygwin_rexec): Ditto. + (socketpair): Ditto. + 2003-02-20 Corinna Vinschen * autoload.cc (GetCompressedFileSize): Add. diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index f0971e9d2..bec3c3eac 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -619,22 +619,25 @@ fhandler_disk_file::opendir (path_conv& real_name) strcpy (dir->__d_dirname, real_name.get_win32 ()); dir->__d_dirent->d_version = __DIRENT_VERSION; cygheap_fdnew fd; - fd = this; - fd->set_nohandle (true); - dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; - /* FindFirstFile doesn't seem to like duplicate /'s. */ - len = strlen (dir->__d_dirname); - if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) - strcat (dir->__d_dirname, "*"); - else - strcat (dir->__d_dirname, "\\*"); /**/ - dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; - dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); + if (fd >= 0) + { + fd = this; + fd->set_nohandle (true); + dir->__d_dirent->d_fd = fd; + dir->__d_u.__d_data.__fh = this; + /* FindFirstFile doesn't seem to like duplicate /'s. */ + len = strlen (dir->__d_dirname); + if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) + strcat (dir->__d_dirname, "*"); + else + strcat (dir->__d_dirname, "\\*"); /**/ + dir->__d_cookie = __DIRENT_COOKIE; + dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__d_dirhash = get_namehash (); - res = dir; + res = dir; + } } syscall_printf ("%p = opendir (%s)", res, get_name ()); diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 0e10ad5c6..6c867f927 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -484,7 +484,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) WSAEVENT ev[2] = { WSA_INVALID_EVENT, signal_arrived }; BOOL secret_check_failed = FALSE; BOOL in_progress = FALSE; - cygheap_fdnew res_fd; /* Allows NULL peer and len parameters. */ struct sockaddr_in peer_dummy; @@ -593,19 +592,28 @@ fhandler_socket::accept (struct sockaddr *peer, int *len) } } - if (res_fd < 0) - /* FIXME: what is correct errno? */; - else if ((SOCKET) res == (SOCKET) INVALID_SOCKET) + if ((SOCKET) res == (SOCKET) INVALID_SOCKET) set_winsock_errno (); else { - fhandler_socket* res_fh = fdsock (res_fd, get_name (), res); - if (get_addr_family () == AF_LOCAL) - res_fh->set_sun_path (get_sun_path ()); - res_fh->set_addr_family (get_addr_family ()); - res_fh->set_socket_type (get_socket_type ()); - res_fh->set_connect_state (CONNECTED); - res = res_fd; + cygheap_fdnew res_fd; + fhandler_socket* res_fh = NULL; + if (res_fd >= 0) + res_fh = fdsock (res_fd, get_name (), res); + if (res_fh) + { + if (get_addr_family () == AF_LOCAL) + res_fh->set_sun_path (get_sun_path ()); + res_fh->set_addr_family (get_addr_family ()); + res_fh->set_socket_type (get_socket_type ()); + res_fh->set_connect_state (CONNECTED); + res = res_fd; + } + else + { + closesocket (res); + res = -1; + } } done: diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index 4316efa69..f8f3519a8 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -74,16 +74,19 @@ fhandler_virtual::opendir (path_conv& pc) strcpy (dir->__d_dirname, get_name ()); dir->__d_dirent->d_version = __DIRENT_VERSION; cygheap_fdnew fd; - fd = this; - fd->set_nohandle (true); - dir->__d_dirent->d_fd = fd; - dir->__d_u.__d_data.__fh = this; - dir->__d_cookie = __DIRENT_COOKIE; - dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; - dir->__d_position = 0; - dir->__d_dirhash = get_namehash (); + if (fd >= 0) + { + fd = this; + fd->set_nohandle (true); + dir->__d_dirent->d_fd = fd; + dir->__d_u.__d_data.__fh = this; + dir->__d_cookie = __DIRENT_COOKIE; + dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__d_dirhash = get_namehash (); - res = dir; + res = dir; + } } syscall_printf ("%p = opendir (%s)", res, get_name ()); diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 99301e3d4..6bfec1fa9 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -540,41 +540,37 @@ cygwin_socket (int af, int type, int protocol) SOCKET soc = 0; fhandler_socket *fh = NULL; - cygheap_fdnew fd; + debug_printf ("socket (%d, %d, %d)", af, type, protocol); - if (fd >= 0) + soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol); + + if (soc == INVALID_SOCKET) { - debug_printf ("socket (%d, %d, %d)", af, type, protocol); - - soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol); - - if (soc == INVALID_SOCKET) - { - set_winsock_errno (); - goto done; - } - - const char *name; - - if (af == AF_INET) - name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); - else - name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); - - fh = fdsock (fd, name, soc); - if (!fh) - { - closesocket (soc); - res = -1; - } - else - { - fh->set_addr_family (af); - fh->set_socket_type (type); - res = fd; - } + set_winsock_errno (); + goto done; } + const char *name; + + if (af == AF_INET) + name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); + else + name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); + + { + cygheap_fdnew fd; + if (fd >= 0) + fh = fdsock (fd, name, soc); + if (fh) + { + fh->set_addr_family (af); + fh->set_socket_type (type); + res = fd; + } + else + closesocket (soc); + } + done: syscall_printf ("%d = socket (%d, %d, %d)", res, af, type, protocol); return res; @@ -1901,6 +1897,7 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, { int res = -1; SOCKET fd2s; + sig_dispatch_pending (0); sigframe thisframe (mainthread); @@ -1910,33 +1907,40 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, (remuser && check_null_str_errno (remuser))) return (int) INVALID_SOCKET; - cygheap_fdnew res_fd; - - if (res_fd < 0) - goto done; - - if (fd2p) - { - cygheap_fdnew newfd (res_fd, false); - - if (*fd2p < 0) - goto done; - *fd2p = newfd; - } - res = rcmd (ahost, inport, locuser, remuser, cmd, fd2p ? &fd2s : NULL); - if (res == (int) INVALID_SOCKET) - goto done; - else + if (res != (int) INVALID_SOCKET) { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; + + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + { + closesocket (res); + res = -1; + } + + if (res >= 0 && fd2p) + { + cygheap_fdnew newfd (res_fd, false); + + fh = NULL; + if (newfd >= 0) + fh = fdsock (*fd2p, "/dev/tcp", fd2s); + if (fh) + *fd2p = newfd; + else + { + closesocket (res); + closesocket (fd2s); + res = -1; + } + } } - if (fd2p) - fdsock (*fd2p, "/dev/tcp", fd2s); - -done: syscall_printf ("%d = rcmd (...)", res); return res; } @@ -1952,19 +1956,19 @@ cygwin_rresvport (int *port) if (check_null_invalid_struct_errno (port)) return -1; - cygheap_fdnew res_fd; + res = rresvport (port); - if (res_fd < 0) - res = -1; - else + if (res != (int) INVALID_SOCKET) { - res = rresvport (port); + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; - if (res != (int) INVALID_SOCKET) - { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; - } + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + res = -1; } syscall_printf ("%d = rresvport (%d)", res, port ? *port : 0); @@ -1987,30 +1991,40 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, (password && check_null_str_errno (password))) return (int) INVALID_SOCKET; - cygheap_fdnew res_fd; - - if (res_fd < 0) - goto done; - if (fd2p) - { - cygheap_fdnew newfd (res_fd); - - if (newfd < 0) - goto done; - *fd2p = newfd; - } res = rexec (ahost, inport, locuser, password, cmd, fd2p ? &fd2s : NULL); - if (res == (int) INVALID_SOCKET) - goto done; - else + if (res != (int) INVALID_SOCKET) { - fdsock (res_fd, "/dev/tcp", res); - res = res_fd; - } - if (fd2p) - fdsock (*fd2p, "/dev/tcp", fd2s); + fhandler_socket *fh = NULL; + cygheap_fdnew res_fd; + + if (res_fd >= 0) + fh = fdsock (res_fd, "/dev/tcp", res); + if (fh) + res = res_fd; + else + { + closesocket (res); + res = -1; + } + + if (res >= 0 && fd2p) + { + cygheap_fdnew newfd (res_fd, false); + + fh = NULL; + if (newfd >= 0) + fh = fdsock (*fd2p, "/dev/tcp", fd2s); + if (fh) + *fd2p = newfd; + else + { + closesocket (res); + closesocket (fd2s); + res = -1; + } + } + } -done: syscall_printf ("%d = rexec (...)", res); return res; } @@ -2024,8 +2038,6 @@ socketpair (int family, int type, int protocol, int *sb) SOCKET insock, outsock, newsock; struct sockaddr_in sock_in, sock_out; int len; - cygheap_fdnew sb0; - fhandler_socket *fh; sig_dispatch_pending (0); sigframe thisframe (mainthread); @@ -2049,19 +2061,6 @@ socketpair (int family, int type, int protocol, int *sb) goto done; } - if (sb0 < 0) - goto done; - else - { - sb[0] = sb0; - cygheap_fdnew sb1 (sb0, false); - - if (sb1 < 0) - goto done; - - sb[1] = sb1; - } - /* create the first socket */ newsock = socket (AF_INET, type, 0); if (newsock == INVALID_SOCKET) @@ -2175,35 +2174,47 @@ socketpair (int family, int type, int protocol, int *sb) insock = newsock; } - res = 0; + { + fhandler_socket *fh = NULL; + cygheap_fdnew sb0; + const char *name; - if (family == AF_LOCAL) - { + if (family == AF_INET) + name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp"); + else + name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket"); - fh = fdsock (sb[0], - type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket", - insock); - fh->set_sun_path (""); - fh->set_addr_family (AF_LOCAL); - fh->set_socket_type (type); - fh = fdsock (sb[1], - type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket", - outsock); - fh->set_sun_path (""); - fh->set_addr_family (AF_LOCAL); - fh->set_socket_type (type); - } - else - { - fh = fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp", - insock); - fh->set_addr_family (AF_INET); - fh->set_socket_type (type); - fh = fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp", - outsock); - fh->set_addr_family (AF_INET); - fh->set_socket_type (type); - } + if (sb0 >= 0) + fh = fdsock (sb0, name, insock); + if (fh) + { + fh->set_sun_path (""); + fh->set_addr_family (family); + fh->set_socket_type (type); + + cygheap_fdnew sb1 (sb0, false); + + fh = NULL; + if (sb1 >= 0) + fh = fdsock (sb1, name, outsock); + if (fh) + { + fh->set_sun_path (""); + fh->set_addr_family (family); + fh->set_socket_type (type); + + sb[0] = sb0; + sb[1] = sb1; + res = 0; + } + } + + if (res == -1) + { + closesocket (insock); + closesocket (outsock); + } + } done: syscall_printf ("%d = socketpair (...)", res);