From c5a4eacc6902e3a09e1074570fb1642974436fab Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 22 Feb 2001 14:51:16 +0000 Subject: [PATCH] * cygerrno.h: Revert previous patch. * errno.cc: Ditto. * dir.cc: Eliminate `dir_suffixes'. (opendir): Remove usage of `dir_suffixes'. (rmdir): Ditto. * fhandler.cc (fhandler_disk_file::open): Remove usage of `inner_suffixes'. * path.cc: Rename `inner_suffixes' to `lnk_suffixes'. (path_conv::check): Remove usage of `inner_suffixes'. (symlink): Ditto. (symlink_info::check): Handle checking for `.lnk' in path_conv exclusively here. (chdir): Remove usage of `dir_suffixes'. * shortcut.c: Eliminate debug_printf lines. (check_shortcut): Don't set error except on failing ReadFile. * spawn.cc: Remove ".lnk" from `std_suffixes'. * syscalls.cc (_unlink): Remove usage of `inner_suffixes'. Remove ".lnk" from `stat_suffixes'. (_rename): Add check for renaming a symlink to keep the ".lnk" suffix after renaming. --- winsup/cygwin/ChangeLog | 23 ++++++++++++++++++++++ winsup/cygwin/cygerrno.h | 15 +-------------- winsup/cygwin/dir.cc | 11 ++--------- winsup/cygwin/errno.cc | 2 +- winsup/cygwin/fhandler.cc | 4 +--- winsup/cygwin/path.cc | 27 +++++++++++++++++++------- winsup/cygwin/shortcut.c | 40 +++++++-------------------------------- winsup/cygwin/spawn.cc | 1 - winsup/cygwin/syscalls.cc | 20 +++++++++++++++++--- 9 files changed, 72 insertions(+), 71 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 283de14e5..9f7d12200 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,26 @@ +Thu Feb 22 15:33:00 2001 Corinna Vinschen + + * cygerrno.h: Revert previous patch. + * errno.cc: Ditto. + * dir.cc: Eliminate `dir_suffixes'. + (opendir): Remove usage of `dir_suffixes'. + (rmdir): Ditto. + * fhandler.cc (fhandler_disk_file::open): Remove usage of + `inner_suffixes'. + * path.cc: Rename `inner_suffixes' to `lnk_suffixes'. + (path_conv::check): Remove usage of `inner_suffixes'. + (symlink): Ditto. + (symlink_info::check): Handle checking for `.lnk' in path_conv + exclusively here. + (chdir): Remove usage of `dir_suffixes'. + * shortcut.c: Eliminate debug_printf lines. + (check_shortcut): Don't set error except on failing ReadFile. + * spawn.cc: Remove ".lnk" from `std_suffixes'. + * syscalls.cc (_unlink): Remove usage of `inner_suffixes'. + Remove ".lnk" from `stat_suffixes'. + (_rename): Add check for renaming a symlink to keep the ".lnk" + suffix after renaming. + Thu Feb 22 13:38:00 2001 Corinna Vinschen * shortcut.c: New file. Provides a C interface to reading of diff --git a/winsup/cygwin/cygerrno.h b/winsup/cygwin/cygerrno.h index ad2fad7a1..dd40819b9 100644 --- a/winsup/cygwin/cygerrno.h +++ b/winsup/cygwin/cygerrno.h @@ -8,20 +8,9 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ -#ifdef __cplusplus -extern "C" { -#endif - -int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ((regparm(2))); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus - void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code) __attribute__ ((regparm(3))); void __stdcall seterrno (const char *, int line) __attribute__ ((regparm(2))); +int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ((regparm(2))); #define __seterrno() seterrno (__FILE__, __LINE__) #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) @@ -43,5 +32,3 @@ class save_errno extern const char *__sp_fn; extern int __sp_ln; - -#endif /* __cplusplus */ diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index bad88c846..c88fbfc57 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -59,13 +59,6 @@ writable_directory (const char *file) #endif } -suffix_info dir_suffixes[] = -{ - suffix_info ("", 1), - suffix_info (".lnk", 1), - suffix_info (NULL) -}; - /* opendir: POSIX 5.1.2.1 */ extern "C" DIR * opendir (const char *dirname) @@ -75,7 +68,7 @@ opendir (const char *dirname) DIR *res = 0; struct stat statbuf; - path_conv real_dirname (dirname, PC_SYM_FOLLOW | PC_FULL, dir_suffixes); + path_conv real_dirname (dirname, PC_SYM_FOLLOW | PC_FULL); if (real_dirname.error) { @@ -331,7 +324,7 @@ rmdir (const char *dir) { int res = -1; - path_conv real_dir (dir, PC_SYM_NOFOLLOW, dir_suffixes); + path_conv real_dir (dir, PC_SYM_NOFOLLOW); if (real_dir.error) { diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index baf2d296e..87a37910b 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -110,7 +110,7 @@ errmap[] = { 0, NULL, 0} }; -extern "C" int __stdcall +int __stdcall geterrno_from_win_error (DWORD code, int deferrno) { for (int i = 0; errmap[i].w != 0; ++i) diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b7ec79b34..40aa50849 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1199,13 +1199,11 @@ fhandler_disk_file::fhandler_disk_file (const char *name) : int fhandler_disk_file::open (const char *path, int flags, mode_t mode) { - extern suffix_info inner_suffixes[]; - 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) ? - PC_SYM_NOFOLLOW : PC_SYM_FOLLOW, inner_suffixes); + 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/path.cc b/winsup/cygwin/path.cc index 33ff8435f..240dcaf48 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -96,9 +96,8 @@ struct symlink_info }; /* These suffixes are the only ones allowed in inner path components. */ -suffix_info inner_suffixes[] = +suffix_info lnk_suffixes[] = { - suffix_info ("", 1), suffix_info (".lnk", 1), suffix_info (NULL) }; @@ -273,7 +272,7 @@ path_conv::check (const char *src, unsigned opt, class if we're working on an inner component of the path */ if (component) { - suff = inner_suffixes; + suff = NULL; sym.pflags = 0; } else @@ -2264,7 +2263,7 @@ symlink (const char *topath, const char *frompath) } #else create_shortcut_header (); - path_conv win32_topath (topath, PC_SYM_NOFOLLOW, inner_suffixes); + path_conv win32_topath (topath, PC_SYM_NOFOLLOW); len = strlen (topath); unsigned short win_len = strlen (win32_topath.get_win32 ()); if (WriteFile (h, shortcut_header, SHORTCUT_HDR_SIZE, &written, NULL) @@ -2404,6 +2403,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) int res = 0; char extbuf[MAX_PATH + 5]; const char *path = in_path; + BOOL check_lnk = FALSE; if (!suffixes) ext_here = NULL; @@ -2414,6 +2414,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) } else { +restart: path = strcpy (extbuf, in_path); ext_here = strchr (path, '\0'); } @@ -2467,6 +2468,13 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) contents, &error, &pflags))) { CloseHandle (h); + /* If searching for `foo' and then finding a `foo.lnk' which is + no shortcut, return the same as if file not found. */ + if (check_lnk) + { + fileattr = (DWORD)-1; + goto out; + } goto file_not_symlink; } else if (sym_check == 2 && @@ -2478,9 +2486,15 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes) } CloseHandle (h); - break; + goto out; } while (suffixes); + if (!check_lnk) + { + suffixes = lnk_suffixes; + check_lnk = TRUE; + goto restart; + } goto out; file_not_symlink: @@ -2628,9 +2642,8 @@ int chdir (const char *dir) { MALLOC_CHECK; - extern suffix_info dir_suffixes[]; syscall_printf ("dir %s", dir); - path_conv path (dir, PC_FULL | PC_SYM_FOLLOW, dir_suffixes); + path_conv path (dir, PC_FULL | PC_SYM_FOLLOW); if (path.error) { diff --git a/winsup/cygwin/shortcut.c b/winsup/cygwin/shortcut.c index 7c05f9db3..87db49a7c 100644 --- a/winsup/cygwin/shortcut.c +++ b/winsup/cygwin/shortcut.c @@ -16,14 +16,11 @@ details. */ #include #include #include -#include "cygerrno.h" #include "shortcut.h" /* This is needed to avoid including path.h which is a pure C++ header. */ #define PATH_SYMLINK MOUNT_SYMLINK -#define debug_printf(x) strcpy (contents, x) - char shortcut_header[SHORTCUT_HDR_SIZE]; BOOL shortcut_initalized = FALSE; @@ -71,25 +68,16 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, hres = CoCreateInstance (&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void **)&psl); if (FAILED (hres)) - { - debug_printf ("CoCreateInstance failed"); - goto close_it; - } + goto close_it; /* Get a pointer to the IPersistFile interface. */ hres = psl->lpVtbl->QueryInterface (psl, &IID_IPersistFile, (void **)&ppf); if (FAILED (hres)) - { - debug_printf ("QueryInterface failed"); - goto close_it; - } + goto close_it; /* Load the shortcut. */ MultiByteToWideChar(CP_ACP, 0, path, -1, wc_path, MAX_PATH); hres = ppf->lpVtbl->Load (ppf, wc_path, STGM_READ); if (FAILED (hres)) - { - debug_printf ("Load failed"); - goto close_it; - } + goto close_it; /* Try the description (containing a POSIX path) first. */ if (fileattr & FILE_ATTRIBUTE_READONLY) { @@ -100,18 +88,14 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, if (! ReadFile (h, file_header, SHORTCUT_HDR_SIZE, &got, 0)) { - debug_printf ("ReadFile failed"); *error = EIO; - goto close_it_dont_set_error; + goto close_it; } if (got == SHORTCUT_HDR_SIZE && !cmp_shortcut_header (file_header)) { hres = psl->lpVtbl->GetDescription (psl, contents, MAX_PATH); if (FAILED (hres)) - { - debug_printf ("GetDescription failed"); - goto close_it; - } + goto close_it; len = strlen (contents); } } @@ -135,27 +119,17 @@ check_shortcut (const char *path, DWORD fileattr, HANDLE h, /* Set relative path inside of IShellLink interface. */ hres = psl->lpVtbl->SetRelativePath (psl, full_path, 0); if (FAILED (hres)) - { - debug_printf ("SetRelativePath failed"); - goto close_it; - } + goto close_it; /* Get the path to the shortcut target. */ hres = psl->lpVtbl->GetPath (psl, contents, MAX_PATH, &wfd, 0); if (FAILED(hres)) - { - debug_printf ("GetPath failed"); - goto close_it; - } + goto close_it; } /* It's a symlink. */ *pflags = PATH_SYMLINK; res = strlen (contents); close_it: - if (FAILED (hres)) - *error = geterrno_from_win_error (HRESULT_CODE (hres), EACCES); - -close_it_dont_set_error: /* Release the pointer to IPersistFile. */ if (ppf) ppf->lpVtbl->Release(ppf); diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index f66875c69..75c3a8d14 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -41,7 +41,6 @@ details. */ static suffix_info std_suffixes[] = { suffix_info (".exe", 1), suffix_info ("", 1), - suffix_info (".lnk", 1), suffix_info (".com"), suffix_info (".cmd"), suffix_info (".bat"), suffix_info (".dll"), suffix_info (NULL) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index efe2c69ea..a43504bfa 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -65,11 +65,10 @@ close_all_files (void) extern "C" int _unlink (const char *ourname) { - extern suffix_info inner_suffixes[]; int res = -1; sigframe thisframe (mainthread); - path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL, inner_suffixes); + path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL); if (win32_name.error) { @@ -1031,7 +1030,6 @@ suffix_info stat_suffixes[] = { suffix_info ("", 1), suffix_info (".exe", 1), - suffix_info (".lnk", 1), suffix_info (NULL) }; @@ -1277,6 +1275,22 @@ _rename (const char *oldpath, const char *newpath) path_conv real_new (newpath, PC_SYM_NOFOLLOW); + /* Shortcut hack. */ + char new_lnk_buf[MAX_PATH + 5]; + if (real_old.issymlink () && !real_new.error) + { + int len_old = strlen (real_old.get_win32 ()); + int len_new = strlen (real_new.get_win32 ()); + if (!strcasecmp (real_old.get_win32 () + len_old - 4, ".lnk") && + strcasecmp (real_new.get_win32 () + len_new - 4, ".lnk")) + { + strcpy (new_lnk_buf, newpath); + strcat (new_lnk_buf, ".lnk"); + newpath = new_lnk_buf; + real_new.check (newpath, PC_SYM_NOFOLLOW); + } + } + if (real_new.error) { set_errno (real_new.error);