* 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.
This commit is contained in:
@ -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))
|
||||
|
Reference in New Issue
Block a user