diff options
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r-- | winsup/cygwin/path.cc | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index a6025b0ba..bef272316 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -2488,7 +2488,7 @@ int chdir (const char *dir) { syscall_printf ("dir %s", dir); - path_conv path (dir); + path_conv path (dir, PC_FULL | PC_SYM_FOLLOW); if (path.error) { @@ -2497,6 +2497,23 @@ chdir (const char *dir) return -1; } + /* Look for trailing path component consisting entirely of dots. This + is needed only in case of chdir since Windows simply ignores count + of dots > 2 here instead of returning an error code. Counts of dots + <= 2 are already eliminated by normalize_posix_path. */ + const char *p = strrchr (dir, '/'); + if (!p) + p = dir; + else + p++; + + int len = strlen (p); + if (len > 2 && strspn (p, ".") == len) + { + set_errno (ENOENT); + return -1; + } + char *native_dir = path.get_win32 (); /* Check to see if path translates to something like C:. @@ -2512,7 +2529,7 @@ chdir (const char *dir) if (res == -1) __seterrno (); else - cygcwd.set (path); + cygcwd.set (path, dir); /* Note that we're accessing cwd.posix without a lock here. I didn't think it was worth locking just for strace. */ @@ -2920,8 +2937,10 @@ cwdstuff::get_initial () It is assumed that the lock for the cwd is acquired if win32_cwd == NULL. */ void -cwdstuff::set (char *win32_cwd) +cwdstuff::set (const char *win32_cwd, const char *posix_cwd) { + char pathbuf[MAX_PATH]; + if (win32_cwd) { lock->acquire (); @@ -2929,14 +2948,15 @@ cwdstuff::set (char *win32_cwd) strcpy (win32, win32_cwd); } - hash = hash_path_name (0, win32); + if (!posix_cwd) + cygwin_shared->mount.conv_to_posix_path (win32, pathbuf, 0); + else + (void) normalize_posix_path (posix_cwd, pathbuf); - /* Turn from Win32 style to our style. */ - char temp[MAX_PATH]; - cygwin_shared->mount.conv_to_posix_path (win32, temp, 0); + posix = (char *) crealloc (posix, strlen (pathbuf) + 1); + strcpy (posix, pathbuf); - posix = (char *) crealloc (posix, strlen (temp) + 1); - strcpy (posix, temp); + hash = hash_path_name (0, win32); if (win32_cwd) lock->release (); |