From 5bc584ba65db809b22dd2e10eb2cef922ca60d26 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Mon, 17 Jul 2000 19:18:21 +0000 Subject: [PATCH] Throughout, eliminate third argument to path_conv and use new PC_* constants for second argument. * path.h: Generalize SYMLINK_* constants to PC_*. (path_conv): Create a new method. Fold third argument into second. * dll_init.cc (dll_list::alloc): Try harder to find space to allocate dll struct. (dll_dllcrt0): Don't check sanity if we've already called dll_crt0. * path.cc (path_conv::check): Don't check for a null or empty path unless specifically told with a flag setting. (check_null_empty_path): New function, adapted from macro. * syscalls.cc (_rename): Use already-determined file attributes rather than checking again. * lib/cygwin/cygwin_attach.dll.c (cygwin_attach_dll): Use a static per_process structure since this is apparently supposed to be zeroed. * lib/cygwin_crt0.c (cygwin_crt0): Zero per_process structure sent to older DLLs. --- winsup/cygwin/ChangeLog | 19 ++++++++++ winsup/cygwin/dcrt0.cc | 29 ++++++++------- winsup/cygwin/dir.cc | 6 ++-- winsup/cygwin/dlfcn.cc | 2 +- winsup/cygwin/dll_init.cc | 52 ++++++++++++++------------- winsup/cygwin/environ.cc | 7 ++-- winsup/cygwin/fhandler.cc | 3 +- winsup/cygwin/fhandler_raw.cc | 2 +- winsup/cygwin/lib/cygwin_attach_dll.c | 2 +- winsup/cygwin/lib/cygwin_crt0.c | 1 + winsup/cygwin/path.cc | 43 ++++++++++++++-------- winsup/cygwin/path.h | 37 +++++++++++-------- winsup/cygwin/security.cc | 2 +- winsup/cygwin/spawn.cc | 2 +- winsup/cygwin/syscalls.cc | 39 ++++++++++---------- 15 files changed, 147 insertions(+), 99 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index aefc514af..c62e309bd 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,22 @@ +Mon Jul 17 14:57:53 2000 Christopher Faylor + + Throughout, eliminate third argument to path_conv and use new PC_* + constants for second argument. + * path.h: Generalize SYMLINK_* constants to PC_*. + (path_conv): Create a new method. Fold third argument into second. + * dll_init.cc (dll_list::alloc): Try harder to find space to allocate + dll struct. + (dll_dllcrt0): Don't check sanity if we've already called dll_crt0. + * path.cc (path_conv::check): Don't check for a null or empty path + unless specifically told with a flag setting. + (check_null_empty_path): New function, adapted from macro. + * syscalls.cc (_rename): Use already-determined file attributes rather + than checking again. + * lib/cygwin/cygwin_attach.dll.c (cygwin_attach_dll): Use a static + per_process structure since this is apparently supposed to be zeroed. + * lib/cygwin_crt0.c (cygwin_crt0): Zero per_process structure sent to + older DLLs. + Mon Jul 17 19:39:00 2000 Corinna Vinschen Patch suggested by Eric Fifer diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 0b6c7012d..283c2f3f4 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -735,26 +735,19 @@ dll_crt0_1 () /* Initialize uid, gid. */ uinfo_init (); - /* beyond this we only do for cygwin apps or dlls */ - if (dynamically_loaded) - { - cygwin_finished_initializing = 1; - return; - } - /* Initialize signal/subprocess handling. */ sigproc_init (); /* Connect to tty. */ tty_init (); + /* Set up standard fds in file descriptor table. */ + hinfo_init (); + if (user_data->premain[0]) for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++) user_data->premain[i] (argc, argv); - /* Set up standard fds in file descriptor table. */ - hinfo_init (); - /* Scan the command line and build argv. Expand wildcards if not called from another cygwin process. */ build_argv (line, argv, argc, @@ -772,11 +765,6 @@ dll_crt0_1 () /* Set up __progname for getopt error call. */ __progname = argv[0]; - /* Flush signals and ensure that signal thread is up and running. Can't - do this for noncygwin case since the signal thread is blocked due to - LoadLibrary serialization. */ - sig_send (NULL, __SIGFLUSH); - cygwin_finished_initializing = 1; /* Call init of loaded dlls. */ dlls.init (); @@ -788,6 +776,17 @@ dll_crt0_1 () debug_printf ("user_data->main %p", user_data->main); + if (dynamically_loaded) + { + set_errno (0); + return; + } + + /* Flush signals and ensure that signal thread is up and running. Can't + do this for noncygwin case since the signal thread is blocked due to + LoadLibrary serialization. */ + sig_send (NULL, __SIGFLUSH); + set_errno (0); if (user_data->main) diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 944313c20..1b409060e 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -59,7 +59,7 @@ opendir (const char *dirname) DIR *res = 0; struct stat statbuf; - path_conv real_dirname (dirname, SYMLINK_FOLLOW, 1); + path_conv real_dirname (dirname, PC_SYM_FOLLOW | PC_FULL); if (real_dirname.error) { @@ -286,7 +286,7 @@ mkdir (const char *dir, mode_t mode) { int res = -1; - path_conv real_dir (dir, SYMLINK_NOFOLLOW); + path_conv real_dir (dir, PC_SYM_NOFOLLOW); if (real_dir.error) { @@ -318,7 +318,7 @@ rmdir (const char *dir) { int res = -1; - path_conv real_dir (dir, SYMLINK_NOFOLLOW); + path_conv real_dir (dir, PC_SYM_NOFOLLOW); if (real_dir.error) { diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index 40931f2a6..cb89edf42 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -145,7 +145,7 @@ get_full_path_of_dll (const char* str) to resolve symlinks etc so that win32 API finds the underlying file. */ if (ret) { - path_conv real_filename (ret, SYMLINK_FOLLOW, 1); + path_conv real_filename (ret, PC_SYM_FOLLOW | PC_FULL); if (real_filename.error) ret = 0; else diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 8f9f4349e..f525a1070 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -106,43 +106,46 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type) return d; /* Return previously allocated pointer. */ } + SYSTEM_INFO s1; + GetSystemInfo (&s1); + int i; void *s = p->bss_end; + DWORD n; MEMORY_BASIC_INFORMATION m; /* Search for space after the DLL */ - for (i = 0; i <= RETRIES; i++) + for (i = 0; i <= RETRIES; i++, s = (char *) m.BaseAddress + m.RegionSize) { if (!VirtualQuery (s, &m, sizeof (m))) return NULL; /* Can't do it. */ if (m.State == MEM_FREE) - break; /* Found some free space */ - s = (char *) m.BaseAddress + m.RegionSize; + { + /* Couldn't find any. Uh oh. FIXME: Issue an error? */ + if (i == RETRIES) + return NULL; /* Oh well. Couldn't locate free space. */ + + /* Ensure that this is rounded to the nearest page boundary. + FIXME: Should this be ensured by VirtualQuery? */ + n = (DWORD) m.BaseAddress; + DWORD r = n % s1.dwAllocationGranularity; + + if (r) + n = ((n - r) + s1.dwAllocationGranularity); + + /* First reserve the area of memory, then commit it. */ + if (VirtualAlloc ((void *) n, sizeof (dll), MEM_RESERVE, PAGE_READWRITE)) + d = (dll *) VirtualAlloc ((void *) n, sizeof (dll), MEM_COMMIT, + PAGE_READWRITE); + if (d) + break; + } } - /* Couldn't find any. Uh oh. FIXME: Issue an error? */ - if (i == RETRIES) - return NULL; /* Oh well. Couldn't locate free space. */ - - SYSTEM_INFO s1; - GetSystemInfo (&s1); - - /* Ensure that this is rounded to the nearest page boundary. - FIXME: Should this be ensured by VirtualQuery? */ - DWORD n = (DWORD) m.BaseAddress; - DWORD r = n % s1.dwAllocationGranularity; - - if (r) - n = ((n - r) + s1.dwAllocationGranularity); - - /* First reserve the area of memory, then commit it. */ - if (VirtualAlloc ((void *) n, sizeof (dll), MEM_RESERVE, PAGE_READWRITE)) - d = (dll *) VirtualAlloc ((void *) n, sizeof (dll), MEM_COMMIT, PAGE_READWRITE); - /* Did we succeed? */ if (d == NULL) { /* Nope. */ #ifdef DEBUGGING - system_printf ("VirtualAlloc failed for %p, %E", n); + system_printf ("VirtualAlloc failed for %E"); #endif __seterrno (); return NULL; @@ -330,8 +333,7 @@ dll_dllcrt0 (HMODULE h, per_process *p) /* Partially initialize Cygwin guts for non-cygwin apps. */ if (dynamically_loaded && user_data->magic_biscuit == 0) dll_crt0 (p); - - if (p) + else check_sanity_and_sync (p); dll_type type; diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index b53600724..7c236df42 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -259,12 +259,13 @@ setenv (const char *name, const char *value, int rewrite) extern "C" void unsetenv (const char *name) { - register char **P; + register char **e; int offset; while (my_findenv (name, &offset)) /* if set multiple times */ - for (P = &environ[offset];; ++P) - if (!(*P = *(P + 1))) + /* Move up the rest of the array */ + for (e = environ + offset; ; e++) + if (!(*e = *(e + 1))) break; } diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 04b4fb3e2..35da0d8fd 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1179,7 +1179,8 @@ fhandler_disk_file::open (const char *path, int flags, mode_t mode) syscall_printf ("(%s, %p)", path, flags); /* O_NOSYMLINK is an internal flag for implementing lstat, nothing more. */ - path_conv real_path (path, (flags & O_NOSYMLINK) ? SYMLINK_NOFOLLOW:SYMLINK_FOLLOW); + path_conv real_path (path, (flags & O_NOSYMLINK) ? + PC_SYM_NOFOLLOW : PC_SYM_FOLLOW); if (real_path.error && (flags & O_NOSYMLINK || real_path.error != ENOENT || !(flags & O_CREAT))) diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index e34151b80..e2703c14f 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -132,7 +132,7 @@ fhandler_dev_raw::de_linearize (const char *buf, const char *unix_name, int fhandler_dev_raw::open (const char *path, int flags, mode_t) { - path_conv real_path (path, SYMLINK_IGNORE); + path_conv real_path (path, PC_SYM_IGNORE); int ret; set_name (path, real_path.get_win32 ()); diff --git a/winsup/cygwin/lib/cygwin_attach_dll.c b/winsup/cygwin/lib/cygwin_attach_dll.c index 440cace57..1791a4bf2 100644 --- a/winsup/cygwin/lib/cygwin_attach_dll.c +++ b/winsup/cygwin/lib/cygwin_attach_dll.c @@ -17,7 +17,7 @@ details. */ int cygwin_attach_dll (HMODULE h, MainFunc f) { - struct per_process u; + static struct per_process u; (void) _cygwin_crt0_common (f, &u); /* jump into the dll. */ diff --git a/winsup/cygwin/lib/cygwin_crt0.c b/winsup/cygwin/lib/cygwin_crt0.c index 785d9f119..0d961786a 100644 --- a/winsup/cygwin/lib/cygwin_crt0.c +++ b/winsup/cygwin/lib/cygwin_crt0.c @@ -25,6 +25,7 @@ cygwin_crt0 (MainFunc f) else /* Older DLL. Provide a per_process */ { u = (struct per_process *) alloca (sizeof (*u)); + memset (u, 0, sizeof (u)); (void) _cygwin_crt0_common (f, u); } dll_crt0__FP11per_process (u); /* Jump into the dll, never to return */ diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 3150ebfdd..fb50a4571 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -182,8 +182,8 @@ path_prefix_p_ (const char *path1, const char *path2, int len1) */ void -path_conv::check (const char *src, symlink_follow follow_mode, - int use_full_path, const suffix_info *suffixes) +path_conv::check (const char *src, unsigned opt, + const suffix_info *suffixes) { /* This array is used when expanding symlinks. It is MAX_PATH * 2 in length so that we can hold the expanded symlink plus a @@ -195,10 +195,12 @@ path_conv::check (const char *src, symlink_follow follow_mode, char *rel_path, *full_path; - if ((error = check_null_empty_path (src))) + if (!(opt & PC_NULLEMPTY)) + error = 0; + else if ((error = check_null_empty_path (src))) return; - if (use_full_path) + if (opt & PC_FULL) rel_path = path_buf, full_path = this->path; else rel_path = this->path, full_path = path_buf; @@ -235,7 +237,7 @@ path_conv::check (const char *src, symlink_follow follow_mode, if (full_path[0] && full_path[1] == ':' && full_path[2] == '\0') strcat (full_path, "\\"); - if (follow_mode == SYMLINK_IGNORE) + if (opt & PC_SYM_IGNORE) { fileattr = GetFileAttributesA (path); goto out; @@ -297,11 +299,11 @@ path_conv::check (const char *src, symlink_follow follow_mode, these operations again on the newly derived path. */ else if (len > 0) { - if (component == 0 && follow_mode != SYMLINK_FOLLOW) + if (component == 0 && !(opt & PC_SYM_FOLLOW)) { set_symlink (); // last component of path is a symlink. fileattr = sym.fileattr; - if (follow_mode == SYMLINK_CONTENTS) + if (opt & PC_SYM_CONTENTS) strcpy (path, sym.contents); goto fillin; } @@ -370,7 +372,7 @@ path_conv::check (const char *src, symlink_follow follow_mode, fillin: if (sym.known_suffix) known_suffix = this->path + (sym.known_suffix - path_copy); - else if (sym.ext_here && follow_mode != SYMLINK_CONTENTS) + else if (sym.ext_here && !(opt & PC_SYM_CONTENTS)) { known_suffix = strchr (this->path, '\0'); strcpy (known_suffix, sym.ext_here); @@ -510,7 +512,7 @@ get_device_number (const char *name, int &unit, BOOL from_conv) else if (! from_conv) devn = get_raw_device_number (name - 5, path_conv (name - 5, - SYMLINK_IGNORE).get_win32 (), + PC_SYM_IGNORE).get_win32 (), unit); } else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0) @@ -1975,7 +1977,7 @@ symlink (const char *topath, const char *frompath) HANDLE h; int res = -1; - path_conv win32_path (frompath, SYMLINK_NOFOLLOW); + path_conv win32_path (frompath, PC_SYM_NOFOLLOW); if (win32_path.error) { set_errno (win32_path.error); @@ -2221,7 +2223,7 @@ int readlink (const char *path, char *buf, int buflen) { extern suffix_info stat_suffixes[]; - path_conv pathbuf (path, SYMLINK_CONTENTS, 0, stat_suffixes); + path_conv pathbuf (path, PC_SYM_CONTENTS, stat_suffixes); if (pathbuf.error) { @@ -2492,7 +2494,7 @@ extern "C" int cygwin_conv_to_win32_path (const char *path, char *win32_path) { - path_conv p (path, SYMLINK_FOLLOW, 0); + path_conv p (path, PC_SYM_FOLLOW); if (p.error) { set_errno (p.error); @@ -2507,7 +2509,7 @@ extern "C" int cygwin_conv_to_full_win32_path (const char *path, char *win32_path) { - path_conv p (path, SYMLINK_FOLLOW, 1); + path_conv p (path, PC_SYM_FOLLOW | PC_FULL); if (p.error) { set_errno (p.error); @@ -2548,7 +2550,7 @@ realpath (const char *path, char *resolved) { int err; - path_conv real_path (path, SYMLINK_FOLLOW, 1); + path_conv real_path (path, PC_SYM_FOLLOW | PC_FULL); if (real_path.error) err = real_path.error; @@ -2807,3 +2809,16 @@ strcasestr (const char *searchee, const char *lookfor) return NULL; } + +int __stdcall +check_null_empty_path (const char *name) +{ + MEMORY_BASIC_INFORMATION m; + if (!name || !VirtualQuery (name, &m, sizeof (m)) || (m.State != MEM_COMMIT)) + return EFAULT; + + if (!*name) + return ENOENT; + + return 0; +} diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 76ab20805..a2b647bec 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -15,17 +15,21 @@ struct suffix_info suffix_info (const char *s, int addit = 0) {name = s, addon = addit;} }; -enum symlink_follow +enum pathconv_arg { - SYMLINK_FOLLOW, - SYMLINK_NOFOLLOW, - SYMLINK_IGNORE, - SYMLINK_CONTENTS + PC_SYM_FOLLOW = 0x0001, + PC_SYM_NOFOLLOW = 0x0002, + PC_SYM_IGNORE = 0x0004, + PC_SYM_CONTENTS = 0x0008, + PC_FULL = 0x0010, + PC_NULLEMPTY = 0x0020 }; +#define PC_NONULLEMPTY -1 + #include -enum +enum path_types { PATH_NOTHING = 0, PATH_SYMLINK = MOUNT_SYMLINK, @@ -36,7 +40,6 @@ enum PATH_HASACLS = 0x80000000 }; - class path_conv { char path[MAX_PATH]; @@ -65,12 +68,19 @@ class path_conv DWORD fileattr; - void check (const char *src, symlink_follow follow_mode = SYMLINK_FOLLOW, - int use_full_path = 0, const suffix_info *suffixes = NULL); - path_conv (const char *src, symlink_follow follow_mode = SYMLINK_FOLLOW, - int use_full_path = 0, const suffix_info *suffixes = NULL) + void check (const char *src, unsigned opt = PC_SYM_FOLLOW, + const suffix_info *suffixes = NULL); + + path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW, + const suffix_info *suffixes = NULL) { - check (src, follow_mode, use_full_path, suffixes); + check (src, opt, suffixes); + } + + path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW, + const suffix_info *suffixes = NULL) + { + check (src, opt | PC_NULLEMPTY, suffixes); } path_conv (): path_flags (0), known_suffix (NULL), error (0), devn (0), unit (0), fileattr (0xffffffff) {path[0] = '\0';} @@ -96,10 +106,9 @@ extern suffix_info std_suffixes[]; int __stdcall get_device_number (const char *name, int &unit, BOOL from_conv = FALSE); int __stdcall slash_unc_prefix_p (const char *path); +int __stdcall check_null_empty_path (const char *name); /* Common macros for checking for invalid path names */ -#define check_null_empty_path(src) \ - (!(src) ? EFAULT : *(src) ? 0 : ENOENT) #define check_null_empty_path_errno(src) \ ({ \ diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 26fc2d1cb..29012bff1 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1570,7 +1570,7 @@ int acl_worker (const char *path, int cmd, int nentries, aclent_t *aclbufp, int nofollow) { - path_conv real_path (path, nofollow ? SYMLINK_NOFOLLOW : SYMLINK_FOLLOW, 1); + path_conv real_path (path, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL); if (real_path.error) { set_errno (real_path.error); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index ca22436fd..063e99ff3 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -43,7 +43,7 @@ perhaps_suffix (const char *prog, path_conv &buf) char *ext; debug_printf ("prog '%s'", prog); - buf.check (prog, SYMLINK_FOLLOW, 1, std_suffixes); + buf.check (prog, PC_SYM_FOLLOW | PC_FULL, std_suffixes); if (buf.file_attributes () & FILE_ATTRIBUTE_DIRECTORY) ext = NULL; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 61479aa29..b237f8264 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -47,7 +47,7 @@ _unlink (const char *ourname) { int res = -1; - path_conv win32_name (ourname, SYMLINK_NOFOLLOW, 1); + path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL); if (win32_name.error) { @@ -494,8 +494,8 @@ int _link (const char *a, const char *b) { int res = -1; - path_conv real_a (a, SYMLINK_NOFOLLOW); - path_conv real_b (b, SYMLINK_NOFOLLOW); + path_conv real_a (a, PC_SYM_NOFOLLOW); + path_conv real_b (b, PC_SYM_NOFOLLOW); if (real_a.error) { @@ -658,18 +658,21 @@ rel2abssd (PSECURITY_DESCRIPTOR psd_rel, PSECURITY_DESCRIPTOR psd_abs, * systems, it is only a stub that always returns zero. */ static int -chown_worker (const char *name, symlink_follow fmode, uid_t uid, gid_t gid) +chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid) { int res; uid_t old_uid; gid_t old_gid; + if (check_null_empty_path_errno(name)) + return -1; + if (os_being_run != winNT) // real chown only works on NT res = 0; // return zero (and do nothing) under Windows 9x else { /* we need Win32 path names because of usage of Win32 API functions */ - path_conv win32_path (name, fmode); + path_conv win32_path (PC_NONULLEMPTY, name, fmode); if (win32_path.error) { @@ -717,7 +720,7 @@ chown_worker (const char *name, symlink_follow fmode, uid_t uid, gid_t gid) done: syscall_printf ("%d = %schown (%s,...)", - res, fmode == SYMLINK_IGNORE ? "l" : "", name); + res, (fmode & PC_SYM_IGNORE) ? "l" : "", name); return res; } @@ -725,14 +728,14 @@ extern "C" int chown (const char * name, uid_t uid, gid_t gid) { - return chown_worker (name, SYMLINK_FOLLOW, uid, gid); + return chown_worker (name, PC_SYM_FOLLOW, uid, gid); } extern "C" int lchown (const char * name, uid_t uid, gid_t gid) { - return chown_worker (name, SYMLINK_IGNORE, uid, gid); + return chown_worker (name, PC_SYM_IGNORE, uid, gid); } extern "C" @@ -757,7 +760,7 @@ fchown (int fd, uid_t uid, gid_t gid) syscall_printf ("fchown (%d,...): calling chown_worker (%s,FOLLOW,...)", fd, path); - return chown_worker (path, SYMLINK_FOLLOW, uid, gid); + return chown_worker (path, PC_SYM_FOLLOW, uid, gid); } /* umask: POSIX 5.3.3.1 */ @@ -1005,7 +1008,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf, debug_printf ("%s (%s, %p)", caller, name, buf); - path_conv real_path (name, nofollow ? SYMLINK_NOFOLLOW : SYMLINK_FOLLOW, 1, + path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) | PC_FULL, stat_suffixes); if (real_path.error) @@ -1193,7 +1196,7 @@ _rename (const char *oldpath, const char *newpath) { int res = 0; - path_conv real_old (oldpath, SYMLINK_NOFOLLOW); + path_conv real_old (oldpath, PC_SYM_NOFOLLOW); if (real_old.error) { @@ -1202,7 +1205,7 @@ _rename (const char *oldpath, const char *newpath) return -1; } - path_conv real_new (newpath, SYMLINK_NOFOLLOW); + path_conv real_new (newpath, PC_SYM_NOFOLLOW); if (real_new.error) { @@ -1218,20 +1221,18 @@ _rename (const char *oldpath, const char *newpath) return -1; } - int oldatts = GetFileAttributesA (real_old.get_win32 ()); - int newatts = GetFileAttributesA (real_new.get_win32 ()); - - if (oldatts == -1) /* file to move doesn't exist */ + if (real_old.file_attributes () == (DWORD) -1) /* file to move doesn't exist */ { syscall_printf ("file to move doesn't exist"); return (-1); } - if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY) + if (real_new.file_attributes () != (DWORD) -1 && + real_new.file_attributes () & FILE_ATTRIBUTE_READONLY) { /* Destination file exists and is read only, change that or else the rename won't work. */ - SetFileAttributesA (real_new.get_win32 (), newatts & ~ FILE_ATTRIBUTE_READONLY); + SetFileAttributesA (real_new.get_win32 (), real_new.file_attributes () & ~ FILE_ATTRIBUTE_READONLY); } if (!MoveFile (real_old.get_win32 (), real_new.get_win32 ())) @@ -1277,7 +1278,7 @@ done: if (res == 0) { /* make the new file have the permissions of the old one */ - SetFileAttributesA (real_new.get_win32 (), oldatts); + SetFileAttributesA (real_new.get_win32 (), real_old.file_attributes ()); } syscall_printf ("%d = rename (%s, %s)", res, real_old.get_win32 (),