diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 21b081815..6cb4c75a4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,18 @@ +Thu Oct 5 20:34:48 2000 Christopher Faylor + + * net.cc (set_socket_inheritance): Rename from duplicate_socket. Use + NT specific call when appropriate. + (__set_winsock_errno): Rename from set_winsock_errno. Accept function + and line as arguments. + * path.cc (path_conv::check): Continue the neverending battle to make + cygwin properly understand that path specs ending in a slash require + that the path refer to a directory. Windows does not do this by + default. + (symlink_info::check): Remove ENOTDIR test. Move it to + path_conv::check. + * path.h: Remove obsolete constant. + * winsup.h (set_winsock_errno): New macro. + Thu Oct 5 14:58:00 2000 Corinna Vinschen * fhandler.h: Add mmap(), munmap() and msync() to fhandler_base diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index e062e2b5c..8f4220637 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -45,24 +45,23 @@ int sscanf (const char *, const char *, ...); } /* End of "C" section */ /* Cygwin internal */ -static SOCKET -duplicate_socket (SOCKET sock) +static SOCKET __stdcall +set_socket_inheritance (SOCKET sock) { - /* Do not duplicate socket on Windows NT because of problems with - MS winsock proxy server. - */ if (os_being_run == winNT) - return sock; - - SOCKET newsock; - if (DuplicateHandle (hMainProc, (HANDLE) sock, hMainProc, (HANDLE *) &newsock, - 0, TRUE, DUPLICATE_SAME_ACCESS)) - { - closesocket (sock); - sock = newsock; - } + (void) SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); else - small_printf ("DuplicateHandle failed %E"); + { + SOCKET newsock; + if (!DuplicateHandle (hMainProc, (HANDLE) sock, hMainProc, (HANDLE *) &newsock, + 0, TRUE, DUPLICATE_SAME_ACCESS)) + small_printf ("DuplicateHandle failed %E"); + else + { + closesocket (sock); + sock = newsock; + } + } return sock; } @@ -233,7 +232,7 @@ static struct tl errmap[] = /* Cygwin internal */ void -set_winsock_errno () +__set_winsock_errno (const char *fn, int ln) { int i; int why = WSAGetLastError (); @@ -243,12 +242,12 @@ set_winsock_errno () if (errmap[i].w != 0) { - syscall_printf ("%d (%s) -> %d", why, errmap[i].s, errmap[i].e); + syscall_printf ("%s:%d - %d (%s) -> %d", fn, ln, why, errmap[i].s, errmap[i].e); set_errno (errmap[i].e); } else { - syscall_printf ("unknown error %d", why); + syscall_printf ("%s:%d - unknown error %d", fn, ln, why); set_errno (EPERM); } } @@ -337,7 +336,7 @@ cygwin_socket (int af, int type, int protocol) goto done; } - soc = duplicate_socket (soc); + soc = set_socket_inheritance (soc); const char *name; if (af == AF_INET) @@ -718,7 +717,7 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) set_winsock_errno (); else { - res = duplicate_socket (res); + res = set_socket_inheritance (res); fdsock (res_fd, sock->get_name (), res); res = res_fd; @@ -1553,14 +1552,14 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, goto done; else { - res = duplicate_socket (res); + res = set_socket_inheritance (res); fdsock (res_fd, "/dev/tcp", res); res = res_fd; } if (fd2p) { - fd2s = duplicate_socket (fd2s); + fd2s = set_socket_inheritance (fd2s); fdsock (*fd2p, "/dev/tcp", fd2s); } @@ -1585,7 +1584,7 @@ cygwin_rresvport (int *port) goto done; else { - res = duplicate_socket (res); + res = set_socket_inheritance (res); fdsock (res_fd, "/dev/tcp", res); res = res_fd; @@ -1618,14 +1617,14 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, goto done; else { - res = duplicate_socket (res); + res = set_socket_inheritance (res); fdsock (res_fd, "/dev/tcp", res); res = res_fd; } if (fd2p) { - fd2s = duplicate_socket (fd2s); + fd2s = set_socket_inheritance (fd2s); fdsock (*fd2p, "/dev/tcp", fd2s); } done: @@ -1726,11 +1725,11 @@ socketpair (int, int type, int, int *sb) closesocket (newsock); res = 0; - insock = duplicate_socket (insock); + insock = set_socket_inheritance (insock); fdsock (sb[0], "/dev/tcp", insock); - outsock = duplicate_socket (outsock); + outsock = set_socket_inheritance (outsock); fdsock (sb[1], "/dev/tcp", outsock); done: diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index ad60e07a1..033a0c5c5 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -168,6 +168,7 @@ path_conv::check (const char *src, unsigned opt, char path_copy[MAX_PATH]; char tmp_buf[MAX_PATH]; symlink_info sym; + bool need_directory = 0; char *rel_path, *full_path; @@ -189,16 +190,15 @@ path_conv::check (const char *src, unsigned opt, for (;;) { MALLOC_CHECK; - DWORD need_directory = 0; char *p = strrchr (src, '/'); if (p) { - if (strcmp (p, "/") == 0 || strcmp (p, "/.") == 0) - need_directory = PATH_NEEDDIR; + if (p[1] == '\0' || strcmp (p, "/.") == 0) + need_directory = 1; } else if ((p = strrchr (src, '\\')) && - (strcmp (p, "\\") == 0 || strcmp (p, "\\.") == 0)) - need_directory = PATH_NEEDDIR; + (p[1] == '\0' || strcmp (p, "\\.") == 0)) + need_directory = 1; /* Must look up path in mount table, etc. */ error = cygwin_shared->mount.conv_to_win32_path (src, rel_path, full_path, @@ -285,7 +285,7 @@ path_conv::check (const char *src, unsigned opt, these operations again on the newly derived path. */ else if (len > 0) { - if (component == 0 && !(opt & PC_SYM_FOLLOW)) + if (component == 0 && !need_directory && !(opt & PC_SYM_FOLLOW)) { set_symlink (); // last component of path is a symlink. fileattr = sym.fileattr; @@ -363,6 +363,18 @@ fillin: } out: + /* Deal with Windows stupidity which considers filename\. to be valid + even when "filename" is not a directory. */ + if (!need_directory || error) + /* nothing to do */; + else if (fileattr & FILE_ATTRIBUTE_DIRECTORY) + path_flags &= ~PATH_SYMLINK; + else + { + debug_printf ("%s is a non-directory", path); + error = ENOTDIR; + return; + } DWORD serial, volflags; strcpy (tmp_buf, full_path); @@ -2187,7 +2199,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) HANDLE h; int res = 0; char extbuf[MAX_PATH + 5]; - int needdir; const char *path = in_path; if (!suffixes) @@ -2206,13 +2217,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) is_symlink = TRUE; error = 0; - if (!(pflags & PATH_NEEDDIR)) - needdir = 0; - else - { - pflags &= ~PATH_NEEDDIR; - needdir = 1; - } do { if (!next_suffix (ext_here, suffixes)) @@ -2229,22 +2233,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) continue; } - /* Windows allows path\. even when `path' isn't a directory. - Detect this scenario and disallow it, since it is non-UNIX like. - FIXME: This code actually checks for things like foo/ and foo/.. - even though those usages have already been (erroneously?) eaten - by cygwin_shared->mount.conv_to_win32_path in path_conv::check. */ - - char *p = strrchr (path, '\\'); - if (p && !(fileattr & FILE_ATTRIBUTE_DIRECTORY) && - (needdir || *++p == '\0' || - (*p == '.' && (*++p == '\0' || (*p == '.' && p[1] == '\0'))))) - { - debug_printf ("%s is a non-directory", path); - error = ENOTDIR; - goto file_not_symlink; - } - /* A symlink will have the `system' file attribute. */ /* Only files can be symlinks (which can be symlinks to directories). */ if (!(pflags & PATH_SYMLINK) && !SYMLINKATTR (fileattr)) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index fdfbfdbba..4c7f2c0e2 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -36,7 +36,6 @@ enum path_types PATH_BINARY = MOUNT_BINARY, PATH_EXEC = MOUNT_EXEC, PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, - PATH_NEEDDIR = 0x20000000, PATH_SOCKET = 0x40000000, PATH_HASACLS = 0x80000000 }; diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index fac12b33f..2deee0e6a 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -201,7 +201,8 @@ long __stdcall to_time_t (FILETIME * ptr); void __stdcall set_console_title (char *); void set_console_handler (); -void set_winsock_errno (); +#define set_winsock_errno() __set_winsock_errno (__FUNCTION__, __LINE__) +void __set_winsock_errno (const char *fn, int ln); /* Printf type functions */ extern "C" void __api_fatal (const char *, ...) __attribute__ ((noreturn));