* dir.cc (mkdir): Check for case clash.
* environ.cc: Add extern declaration for `pcheck_case'. (check_case_init): New function. (struct parse_thing): Add "check_case" option. * errno.cc (_sys_nerrlist): Add text for ECASECLASH. (strerror): Add case branch for ECASECLASH. * fhandler.cc (fhandler_disk_file::open): Check for case clash. * path.cc: Add global variable `pcheck_case'. (struct symlink_info): Add member `case_clash' and method `case_check'. (path_prefix_p_): Call `pathnmatch' instead of `strncasematch'. (pathnmatch): New funtion. (pathmatch): Ditto. (path_conv::check): Add handling for case checking. (symlink): Check for case clash. (symlink_info::check): Add parameter for case checking. Handle case checking. (symlink_info::case_check): New method. (chdir): Don't use unconverted path if pcheck_case==PCHECK_STRICT. * path.h: Add extern declarations for `pathmatch' and `pathnmatch'. (enum case_checking): New enumeration type describing the case checking behaviour of path conversion routines. (class path_conv): Add member `case_clash'. * syscalls.cc (_link): Check for case clash.
This commit is contained in:
parent
b8a8c59d33
commit
70c370d674
@ -1,3 +1,30 @@
|
|||||||
|
Thu Apr 17 23:19:00 2001 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* dir.cc (mkdir): Check for case clash.
|
||||||
|
* environ.cc: Add extern declaration for `pcheck_case'.
|
||||||
|
(check_case_init): New function.
|
||||||
|
(struct parse_thing): Add "check_case" option.
|
||||||
|
* errno.cc (_sys_nerrlist): Add text for ECASECLASH.
|
||||||
|
(strerror): Add case branch for ECASECLASH.
|
||||||
|
* fhandler.cc (fhandler_disk_file::open): Check for case clash.
|
||||||
|
* path.cc: Add global variable `pcheck_case'.
|
||||||
|
(struct symlink_info): Add member `case_clash' and method `case_check'.
|
||||||
|
(path_prefix_p_): Call `pathnmatch' instead of `strncasematch'.
|
||||||
|
(pathnmatch): New funtion.
|
||||||
|
(pathmatch): Ditto.
|
||||||
|
(path_conv::check): Add handling for case checking.
|
||||||
|
(symlink): Check for case clash.
|
||||||
|
(symlink_info::check): Add parameter for case checking.
|
||||||
|
Handle case checking.
|
||||||
|
(symlink_info::case_check): New method.
|
||||||
|
(chdir): Don't use unconverted path if pcheck_case==PCHECK_STRICT.
|
||||||
|
* path.h: Add extern declarations for `pathmatch' and
|
||||||
|
`pathnmatch'.
|
||||||
|
(enum case_checking): New enumeration type describing
|
||||||
|
the case checking behaviour of path conversion routines.
|
||||||
|
(class path_conv): Add member `case_clash'.
|
||||||
|
* syscalls.cc (_link): Check for case clash.
|
||||||
|
|
||||||
Thu Apr 12 12:49:53 2001 Christopher Faylor <cgf@cygnus.com>
|
Thu Apr 12 12:49:53 2001 Christopher Faylor <cgf@cygnus.com>
|
||||||
|
|
||||||
* syscalls.cc (mkfifo): New function stub.
|
* syscalls.cc (mkfifo): New function stub.
|
||||||
|
@ -306,7 +306,7 @@ mkdir (const char *dir, mode_t mode)
|
|||||||
|
|
||||||
if (real_dir.error)
|
if (real_dir.error)
|
||||||
{
|
{
|
||||||
set_errno (real_dir.error);
|
set_errno (real_dir.case_clash ? ECASECLASH : real_dir.error);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ extern BOOL allow_ntea;
|
|||||||
extern BOOL allow_smbntsec;
|
extern BOOL allow_smbntsec;
|
||||||
extern BOOL allow_winsymlinks;
|
extern BOOL allow_winsymlinks;
|
||||||
extern BOOL strip_title_path;
|
extern BOOL strip_title_path;
|
||||||
|
extern int pcheck_case;
|
||||||
extern DWORD chunksize;
|
extern DWORD chunksize;
|
||||||
BOOL reset_com = TRUE;
|
BOOL reset_com = TRUE;
|
||||||
static BOOL envcache = TRUE;
|
static BOOL envcache = TRUE;
|
||||||
@ -393,6 +394,33 @@ glob_init (const char *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_case_init (const char *buf)
|
||||||
|
{
|
||||||
|
if (!buf || !*buf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strncmp (buf, "relax", 5)== 0)
|
||||||
|
{
|
||||||
|
pcheck_case = PCHECK_RELAXED;
|
||||||
|
debug_printf ("File case checking set to RELAXED");
|
||||||
|
}
|
||||||
|
else if (strcmp (buf, "adjust")== 0)
|
||||||
|
{
|
||||||
|
pcheck_case = PCHECK_ADJUST;
|
||||||
|
debug_printf ("File case checking set to ADJUST");
|
||||||
|
}
|
||||||
|
else if (strcmp (buf, "strict")== 0)
|
||||||
|
{
|
||||||
|
pcheck_case = PCHECK_STRICT;
|
||||||
|
debug_printf ("File case checking set to STRICT");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf ("Wrong case checking name: %s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
codepage_init (const char *buf)
|
codepage_init (const char *buf)
|
||||||
{
|
{
|
||||||
@ -441,6 +469,7 @@ struct parse_thing
|
|||||||
} known[] =
|
} known[] =
|
||||||
{
|
{
|
||||||
{"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},
|
{"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}},
|
||||||
|
{"check_case", {func: &check_case_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
{"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}},
|
{"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
{"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}},
|
{"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}},
|
||||||
{"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}},
|
{"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
|
@ -283,7 +283,8 @@ extern const char __declspec(dllexport) * const _sys_errlist[]=
|
|||||||
/* ESTALE 133 */ "Stale NFS file handle",
|
/* ESTALE 133 */ "Stale NFS file handle",
|
||||||
/* ENOTSUP 134 */ "134",
|
/* ENOTSUP 134 */ "134",
|
||||||
/* ENOMEDIUM 135 */ "no medium",
|
/* ENOMEDIUM 135 */ "no medium",
|
||||||
/* ENOSHARE 136 */ "No such host or network path"
|
/* ENOSHARE 136 */ "No such host or network path",
|
||||||
|
/* ECASECLASH 137 */ "Filename exists with different case"
|
||||||
};
|
};
|
||||||
|
|
||||||
int __declspec(dllexport) _sys_nerr =
|
int __declspec(dllexport) _sys_nerr =
|
||||||
@ -659,6 +660,9 @@ strerror (int errnum)
|
|||||||
case ENOSHARE:
|
case ENOSHARE:
|
||||||
error = "No such host or network path";
|
error = "No such host or network path";
|
||||||
break;
|
break;
|
||||||
|
case ECASECLASH:
|
||||||
|
error = "Filename exists with different case";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef _MT_SAFE
|
#ifdef _MT_SAFE
|
||||||
char *buf= _reent_winsup()->_strerror_buf;
|
char *buf= _reent_winsup()->_strerror_buf;
|
||||||
|
@ -1208,9 +1208,11 @@ fhandler_disk_file::open (const char *path, int flags, mode_t mode)
|
|||||||
PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);
|
PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);
|
||||||
|
|
||||||
if (real_path.error &&
|
if (real_path.error &&
|
||||||
(flags & O_NOSYMLINK || real_path.error != ENOENT || !(flags & O_CREAT)))
|
(flags & O_NOSYMLINK || real_path.error != ENOENT
|
||||||
|
|| !(flags & O_CREAT) || real_path.case_clash))
|
||||||
{
|
{
|
||||||
set_errno (real_path.error);
|
set_errno (flags & O_CREAT && real_path.case_clash ? ECASECLASH
|
||||||
|
: real_path.error);
|
||||||
syscall_printf ("0 = fhandler_disk_file::open (%s, %p)", path, flags);
|
syscall_printf ("0 = fhandler_disk_file::open (%s, %p)", path, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -101,12 +101,17 @@ struct symlink_info
|
|||||||
int is_symlink;
|
int is_symlink;
|
||||||
bool ext_tacked_on;
|
bool ext_tacked_on;
|
||||||
int error;
|
int error;
|
||||||
|
BOOL case_clash;
|
||||||
symlink_info (): contents (buf + MAX_PATH + 1) {}
|
symlink_info (): contents (buf + MAX_PATH + 1) {}
|
||||||
int check (const char *path, const suffix_info *suffixes);
|
int check (const char *path, const suffix_info *suffixes,
|
||||||
|
char *orig_path, BOOL sym_ignore);
|
||||||
|
BOOL case_check (const char *path, char *orig_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
cwdstuff cygcwd; /* The current working directory. */
|
cwdstuff cygcwd; /* The current working directory. */
|
||||||
|
|
||||||
|
int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
|
||||||
|
|
||||||
#define path_prefix_p(p1, p2, l1) \
|
#define path_prefix_p(p1, p2, l1) \
|
||||||
((cyg_tolower(*(p1))==cyg_tolower(*(p2))) && \
|
((cyg_tolower(*(p1))==cyg_tolower(*(p2))) && \
|
||||||
path_prefix_p_(p1, p2, l1))
|
path_prefix_p_(p1, p2, l1))
|
||||||
@ -150,12 +155,30 @@ path_prefix_p_ (const char *path1, const char *path2, int len1)
|
|||||||
if (len1 == 0)
|
if (len1 == 0)
|
||||||
return SLASH_P (path2[0]) && !SLASH_P (path2[1]);
|
return SLASH_P (path2[0]) && !SLASH_P (path2[1]);
|
||||||
|
|
||||||
if (!strncasematch (path1, path2, len1))
|
if (!pathnmatch (path1, path2, len1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return SLASH_P (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':';
|
return SLASH_P (path2[len1]) || path2[len1] == 0 || path1[len1 - 1] == ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return non-zero if paths match in first len chars.
|
||||||
|
Check is dependent of the case sensitivity setting. */
|
||||||
|
int
|
||||||
|
pathnmatch (const char *path1, const char *path2, int len)
|
||||||
|
{
|
||||||
|
return pcheck_case == PCHECK_STRICT ? !strncmp (path1, path2, len)
|
||||||
|
: strncasematch (path1, path2, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return non-zero if paths match. Check is dependent of the case
|
||||||
|
sensitivity setting. */
|
||||||
|
int
|
||||||
|
pathmatch (const char *path1, const char *path2)
|
||||||
|
{
|
||||||
|
return pcheck_case == PCHECK_STRICT ? !strcmp (path1, path2)
|
||||||
|
: strcasematch (path1, path2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
|
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
|
||||||
passing to Win32 API routines.
|
passing to Win32 API routines.
|
||||||
|
|
||||||
@ -211,6 +234,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
path_flags = 0;
|
path_flags = 0;
|
||||||
known_suffix = NULL;
|
known_suffix = NULL;
|
||||||
fileattr = (DWORD) -1;
|
fileattr = (DWORD) -1;
|
||||||
|
case_clash = FALSE;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
MALLOC_CHECK;
|
MALLOC_CHECK;
|
||||||
@ -247,7 +271,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
if (full_path[0] && full_path[1] == ':' && full_path[2] == '\0')
|
if (full_path[0] && full_path[1] == ':' && full_path[2] == '\0')
|
||||||
strcat (full_path, "\\");
|
strcat (full_path, "\\");
|
||||||
|
|
||||||
if (opt & PC_SYM_IGNORE)
|
if ((opt & PC_SYM_IGNORE) && pcheck_case == PCHECK_RELAXED)
|
||||||
{
|
{
|
||||||
fileattr = GetFileAttributesA (path);
|
fileattr = GetFileAttributesA (path);
|
||||||
goto out;
|
goto out;
|
||||||
@ -284,44 +308,77 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
sym.pflags = path_flags;
|
sym.pflags = path_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = sym.check (path_copy, suff);
|
int len = sym.check (path_copy, suff, full_path, opt & PC_SYM_IGNORE);
|
||||||
|
|
||||||
if (!component)
|
if (sym.case_clash)
|
||||||
path_flags = sym.pflags;
|
|
||||||
|
|
||||||
/* If symlink.check found an existing non-symlink file, then
|
|
||||||
it sets the appropriate flag. It also sets any suffix found
|
|
||||||
into `ext_here'. */
|
|
||||||
if (!sym.is_symlink && sym.fileattr != (DWORD) -1)
|
|
||||||
{
|
{
|
||||||
error = sym.error;
|
case_clash = TRUE;
|
||||||
if (component == 0)
|
error = ENOENT;
|
||||||
{
|
goto out;
|
||||||
fileattr = sym.fileattr;
|
|
||||||
goto fillin;
|
|
||||||
}
|
|
||||||
goto out; // file found
|
|
||||||
}
|
|
||||||
/* Found a symlink if len > 0. If component == 0, then the
|
|
||||||
src path itself was a symlink. If !follow_mode then
|
|
||||||
we're done. Otherwise we have to insert the path found
|
|
||||||
into the full path that we are building and perform all of
|
|
||||||
these operations again on the newly derived path. */
|
|
||||||
else if (len > 0)
|
|
||||||
{
|
|
||||||
saw_symlinks = 1;
|
|
||||||
if (component == 0 && !need_directory && !(opt & PC_SYM_FOLLOW))
|
|
||||||
{
|
|
||||||
set_symlink (); // last component of path is a symlink.
|
|
||||||
fileattr = sym.fileattr;
|
|
||||||
if (opt & PC_SYM_CONTENTS)
|
|
||||||
strcpy (path, sym.contents);
|
|
||||||
goto fillin;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No existing file found. */
|
if (!(opt & PC_SYM_IGNORE))
|
||||||
|
{
|
||||||
|
if (!component)
|
||||||
|
path_flags = sym.pflags;
|
||||||
|
|
||||||
|
/* If symlink.check found an existing non-symlink file, then
|
||||||
|
it sets the appropriate flag. It also sets any suffix found
|
||||||
|
into `ext_here'. */
|
||||||
|
if (!sym.is_symlink && sym.fileattr != (DWORD) -1)
|
||||||
|
{
|
||||||
|
error = sym.error;
|
||||||
|
if (component == 0)
|
||||||
|
{
|
||||||
|
fileattr = sym.fileattr;
|
||||||
|
if (sym.ext_here && *sym.ext_here)
|
||||||
|
{
|
||||||
|
known_suffix = this->path + sym.extn;
|
||||||
|
if (sym.ext_tacked_on)
|
||||||
|
strcpy (known_suffix, sym.ext_here);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pcheck_case == PCHECK_RELAXED)
|
||||||
|
goto out; // file found
|
||||||
|
/* Avoid further symlink evaluation. Only case checks are
|
||||||
|
done now. */
|
||||||
|
opt |= PC_SYM_IGNORE;
|
||||||
|
}
|
||||||
|
/* Found a symlink if len > 0. If component == 0, then the
|
||||||
|
src path itself was a symlink. If !follow_mode then
|
||||||
|
we're done. Otherwise we have to insert the path found
|
||||||
|
into the full path that we are building and perform all of
|
||||||
|
these operations again on the newly derived path. */
|
||||||
|
else if (len > 0)
|
||||||
|
{
|
||||||
|
saw_symlinks = 1;
|
||||||
|
if (component == 0 && !need_directory && !(opt & PC_SYM_FOLLOW))
|
||||||
|
{
|
||||||
|
set_symlink (); // last component of path is a symlink.
|
||||||
|
fileattr = sym.fileattr;
|
||||||
|
if (opt & PC_SYM_CONTENTS)
|
||||||
|
{
|
||||||
|
strcpy (path, sym.contents);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (sym.ext_here && *sym.ext_here)
|
||||||
|
{
|
||||||
|
known_suffix = this->path + sym.extn;
|
||||||
|
if (sym.ext_tacked_on)
|
||||||
|
strcpy (known_suffix, sym.ext_here);
|
||||||
|
}
|
||||||
|
if (pcheck_case == PCHECK_RELAXED)
|
||||||
|
goto out;
|
||||||
|
/* Avoid further symlink evaluation. Only case checks are
|
||||||
|
done now. */
|
||||||
|
opt |= PC_SYM_IGNORE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* No existing file found. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!(tail = strrchr (path_copy, '\\')) ||
|
if (!(tail = strrchr (path_copy, '\\')) ||
|
||||||
(tail > path_copy && tail[-1] == ':'))
|
(tail > path_copy && tail[-1] == ':'))
|
||||||
@ -378,7 +435,7 @@ path_conv::check (const char *src, unsigned opt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fillin:
|
/*fillin:*/
|
||||||
if (sym.ext_here && *sym.ext_here && !(opt & PC_SYM_CONTENTS))
|
if (sym.ext_here && *sym.ext_here && !(opt & PC_SYM_CONTENTS))
|
||||||
{
|
{
|
||||||
known_suffix = this->path + sym.extn;
|
known_suffix = this->path + sym.extn;
|
||||||
@ -399,6 +456,7 @@ out:
|
|||||||
error = ENOTDIR;
|
error = ENOTDIR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD serial, volflags;
|
DWORD serial, volflags;
|
||||||
char fs_name[16];
|
char fs_name[16];
|
||||||
|
|
||||||
@ -2258,18 +2316,17 @@ symlink (const char *topath, const char *frompath)
|
|||||||
char w32topath[MAX_PATH + 1];
|
char w32topath[MAX_PATH + 1];
|
||||||
DWORD written;
|
DWORD written;
|
||||||
|
|
||||||
if (allow_winsymlinks)
|
win32_path.check (frompath, PC_SYM_NOFOLLOW);
|
||||||
|
if (allow_winsymlinks && !win32_path.error)
|
||||||
{
|
{
|
||||||
strcpy (from, frompath);
|
strcpy (from, frompath);
|
||||||
strcat (from, ".lnk");
|
strcat (from, ".lnk");
|
||||||
win32_path.check (from, PC_SYM_NOFOLLOW);
|
win32_path.check (from, PC_SYM_NOFOLLOW);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
win32_path.check (frompath, PC_SYM_NOFOLLOW);
|
|
||||||
|
|
||||||
if (win32_path.error)
|
if (win32_path.error)
|
||||||
{
|
{
|
||||||
set_errno (win32_path.error);
|
set_errno (win32_path.case_clash ? ECASECLASH : win32_path.error);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2573,7 +2630,8 @@ suffix_scan::next ()
|
|||||||
stored into BUF if PATH is a symlink. */
|
stored into BUF if PATH is a symlink. */
|
||||||
|
|
||||||
int
|
int
|
||||||
symlink_info::check (const char *path, const suffix_info *suffixes)
|
symlink_info::check (const char *path, const suffix_info *suffixes,
|
||||||
|
char *orig_path, BOOL sym_ignore)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@ -2585,6 +2643,8 @@ symlink_info::check (const char *path, const suffix_info *suffixes)
|
|||||||
|
|
||||||
ext_tacked_on = !*ext_here;
|
ext_tacked_on = !*ext_here;
|
||||||
|
|
||||||
|
case_clash = FALSE;
|
||||||
|
|
||||||
while (suffix.next ())
|
while (suffix.next ())
|
||||||
{
|
{
|
||||||
error = 0;
|
error = 0;
|
||||||
@ -2599,6 +2659,10 @@ symlink_info::check (const char *path, const suffix_info *suffixes)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pcheck_case != PCHECK_RELAXED && !case_check (path, orig_path)
|
||||||
|
|| sym_ignore)
|
||||||
|
goto file_not_symlink;
|
||||||
|
|
||||||
int sym_check = 0;
|
int sym_check = 0;
|
||||||
|
|
||||||
if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
if (fileattr & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
@ -2662,6 +2726,50 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check the correct case of the last path component (given in DOS style).
|
||||||
|
Adjust the case in this->path if pcheck_case == PCHECK_ADJUST or return
|
||||||
|
FALSE if pcheck_case == PCHECK_STRICT.
|
||||||
|
Dont't call if pcheck_case == PCHECK_RELAXED.
|
||||||
|
*/
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
symlink_info::case_check (const char *path, char *orig_path)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATA data;
|
||||||
|
HANDLE h;
|
||||||
|
const char *c;
|
||||||
|
|
||||||
|
/* Set a pointer to the beginning of the last component. */
|
||||||
|
if (!(c = strrchr (path, '\\')))
|
||||||
|
c = path;
|
||||||
|
else
|
||||||
|
++c;
|
||||||
|
|
||||||
|
if ((h = FindFirstFile (path, &data))
|
||||||
|
!= INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
FindClose (h);
|
||||||
|
|
||||||
|
/* If that part of the component exists, check the case. */
|
||||||
|
if (strcmp (c, data.cFileName))
|
||||||
|
{
|
||||||
|
/* If check is set to STRICT, a wrong case results
|
||||||
|
in returning a ENOENT. */
|
||||||
|
if (pcheck_case == PCHECK_STRICT)
|
||||||
|
{
|
||||||
|
case_clash = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PCHECK_ADJUST adjusts the case in the incoming
|
||||||
|
path which points to the path in *this. */
|
||||||
|
strncpy (orig_path + (c - path), data.cFileName,
|
||||||
|
strlen (data.cFileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* readlink system call */
|
/* readlink system call */
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -2855,7 +2963,8 @@ chdir (const char *dir)
|
|||||||
we'll see if Cygwin mailing list users whine about the current behavior. */
|
we'll see if Cygwin mailing list users whine about the current behavior. */
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
else if (!path.has_symlinks () && strpbrk (dir, ":\\") == NULL)
|
else if (!path.has_symlinks () && strpbrk (dir, ":\\") == NULL
|
||||||
|
&& pcheck_case == PCHECK_RELAXED)
|
||||||
cygcwd.set (path, dir);
|
cygcwd.set (path, dir);
|
||||||
else
|
else
|
||||||
cygcwd.set (path, NULL);
|
cygcwd.set (path, NULL);
|
||||||
|
@ -25,6 +25,13 @@ enum pathconv_arg
|
|||||||
PC_NULLEMPTY = 0x0020
|
PC_NULLEMPTY = 0x0020
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum case_checking
|
||||||
|
{
|
||||||
|
PCHECK_RELAXED = 0,
|
||||||
|
PCHECK_ADJUST = 1,
|
||||||
|
PCHECK_STRICT = 2
|
||||||
|
};
|
||||||
|
|
||||||
#define PC_NONULLEMPTY -1
|
#define PC_NONULLEMPTY -1
|
||||||
|
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
@ -89,6 +96,8 @@ class path_conv
|
|||||||
|
|
||||||
DWORD fileattr;
|
DWORD fileattr;
|
||||||
|
|
||||||
|
BOOL case_clash;
|
||||||
|
|
||||||
void check (const char *src, unsigned opt = PC_SYM_FOLLOW,
|
void check (const char *src, unsigned opt = PC_SYM_FOLLOW,
|
||||||
const suffix_info *suffixes = NULL) __attribute__ ((regparm(3)));
|
const suffix_info *suffixes = NULL) __attribute__ ((regparm(3)));
|
||||||
|
|
||||||
@ -171,3 +180,6 @@ struct cwdstuff
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern cwdstuff cygcwd;
|
extern cwdstuff cygcwd;
|
||||||
|
|
||||||
|
extern int pathmatch (const char *path1, const char *path2);
|
||||||
|
extern int pathnmatch (const char *path1, const char *path2, int len);
|
||||||
|
@ -545,7 +545,7 @@ _link (const char *a, const char *b)
|
|||||||
}
|
}
|
||||||
if (real_b.error)
|
if (real_b.error)
|
||||||
{
|
{
|
||||||
set_errno (real_b.error);
|
set_errno (real_b.case_clash ? ECASECLASH : real_b.error);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user