diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 02ff7119d..ab308e5b3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +Sat Sep 9 23:29:17 2000 Christopher Faylor + + * path.cc (chdir): Use the full path for cwd_win32. Consider attempts + to chdir to strings of dots > 2 to be an error. Pass 'dir' argument to + cygcwd.set. + (cwdstuff::set): Need to treat arguments from chdir differently. + * path.h (cwdstuff): Add an argument to set. + Fri Sep 8 11:50:09 2000 Christopher Faylor * lib/_cygwin_crt0_common.cc: Add missing header files. 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,15 +2948,16 @@ cwdstuff::set (char *win32_cwd) strcpy (win32, win32_cwd); } + if (!posix_cwd) + cygwin_shared->mount.conv_to_posix_path (win32, pathbuf, 0); + else + (void) normalize_posix_path (posix_cwd, pathbuf); + + posix = (char *) crealloc (posix, strlen (pathbuf) + 1); + strcpy (posix, pathbuf); + hash = hash_path_name (0, win32); - /* 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 (temp) + 1); - strcpy (posix, temp); - if (win32_cwd) lock->release (); diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 01c965752..4c7f2c0e2 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -139,7 +139,7 @@ struct cwdstuff void fixup_after_exec (char *win32, char *posix, DWORD hash); bool get_initial (); void copy (char * &posix_cwd, char * &win32_cwd, DWORD hash_cwd); - void set (char *win32_cwd); + void set (const char *win32_cwd, const char *posix_cwd = NULL); }; extern cwdstuff cygcwd;