* 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:
Corinna Vinschen 2001-02-22 14:51:16 +00:00
parent 79e56091c9
commit c5a4eacc69
9 changed files with 72 additions and 71 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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)
{

View File

@ -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)

View File

@ -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)))

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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);