* 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.
This commit is contained in:
parent
79e56091c9
commit
c5a4eacc69
|
@ -1,3 +1,26 @@
|
|||
Thu Feb 22 15:33:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* 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 <corinna@vinschen.de>
|
||||
|
||||
* shortcut.c: New file. Provides a C interface to reading of
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -16,14 +16,11 @@ details. */
|
|||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <errno.h>
|
||||
#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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue