Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-08-16 14:41:45 +0400
committerCorinna Vinschen <corinna@vinschen.de>2007-08-16 14:41:45 +0400
commit855e63eb4b1ea80dd892309e2bcd214626a90611 (patch)
tree1cc76ce8085ccddd3a47163c4fa09d092f28a8af
parentc4bd83770022e78e9fbd7f1eefb57ad7c69456cd (diff)
* ntdll.h (RtlCreateUnicodeStringFromAsciiz): Fix declaration.
(RtlUpcaseUnicodeChar): Declare. * path.cc (hash_path_name): Split into three functions, taking the path as char *, PWCSTR, or PUNICODE_STRING. Move implementation into PUNICODE_STRING-based function. Drop old drive-relative path consideration. * winsup.h (iswdirsep): Like isdirsep but for WCHARs. (isabspath_u): Like isabspath, for PUNICODE_STRINGs. (iswabspath): Like isabspath, for PWCHARs. (hash_path_name): Add new declarations.
-rw-r--r--winsup/cygwin/ChangeLog13
-rw-r--r--winsup/cygwin/ntdll.h3
-rw-r--r--winsup/cygwin/path.cc80
-rw-r--r--winsup/cygwin/winsup.h20
4 files changed, 70 insertions, 46 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 5b9ba01ff..9c953eb46 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,16 @@
+2007-08-16 Corinna Vinschen <corinna@vinschen.de>
+
+ * ntdll.h (RtlCreateUnicodeStringFromAsciiz): Fix declaration.
+ (RtlUpcaseUnicodeChar): Declare.
+ * path.cc (hash_path_name): Split into three functions, taking
+ the path as char *, PWCSTR, or PUNICODE_STRING. Move implementation
+ into PUNICODE_STRING-based function. Drop old drive-relative path
+ consideration.
+ * winsup.h (iswdirsep): Like isdirsep but for WCHARs.
+ (isabspath_u): Like isabspath, for PUNICODE_STRINGs.
+ (iswabspath): Like isabspath, for PWCHARs.
+ (hash_path_name): Add new declarations.
+
2007-08-15 Corinna Vinschen <corinna@vinschen.de>
* path.cc (get_nt_native_path): Allow to convert special paths which
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 467c9e496..7b8c556b9 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -833,7 +833,7 @@ extern "C"
BOOLEAN);
NTSTATUS NTAPI RtlConvertSidToUnicodeString (PUNICODE_STRING, PSID, BOOLEAN);
VOID NTAPI RtlCopyUnicodeString (PUNICODE_STRING, PUNICODE_STRING);
- ULONG WINAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR);
+ BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR);
BOOLEAN NTAPI RtlEqualUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
BOOLEAN);
VOID NTAPI RtlFreeAnsiString (PANSI_STRING);
@@ -853,6 +853,7 @@ extern "C"
BOOLEAN);
NTSTATUS NTAPI RtlUnicodeStringToOemString (PANSI_STRING, PUNICODE_STRING,
BOOLEAN);
+ WCHAR NTAPI RtlUpcaseUnicodeChar (WCHAR);
/* A few Rtl functions are either actually macros, or they just don't
exist even though they would be a big help. We implement them here,
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 9b20322b8..5a0bc903b 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -80,6 +80,7 @@ details. */
#include <assert.h>
#include <ntdll.h>
#include <wchar.h>
+#include <wctype.h>
bool dos_file_warning = true;
static int normalize_win32_path (const char *, char *, char *&);
@@ -3740,62 +3741,51 @@ readlink (const char *path, char *buf, int buflen)
done during the opendir call and the hash or the filename within
the directory. FIXME: Not bullet-proof. */
/* Cygwin internal */
-
__ino64_t __stdcall
-hash_path_name (__ino64_t hash, const char *name)
+hash_path_name (__ino64_t hash, PUNICODE_STRING name)
{
- if (!*name)
+ if (name->Length == 0)
return hash;
- /* Perform some initial permutations on the pathname if this is
- not "seeded" */
- if (!hash)
- {
- /* Simplistic handling of drives. If there is a drive specified,
- make sure that the initial letter is upper case. If there is
- no \ after the ':' assume access through the root directory
- of that drive.
- FIXME: Should really honor MS-Windows convention of using
- the environment to track current directory on various drives. */
- if (name[1] == ':')
- {
- char *nn, *newname = (char *) alloca (strlen (name) + 2);
- nn = newname;
- *nn = isupper (*name) ? cyg_tolower (*name) : *name;
- *++nn = ':';
- name += 2;
- if (*name != '\\')
- *++nn = '\\';
- strcpy (++nn, name);
- name = newname;
- goto hashit;
- }
-
- /* Fill out the hashed path name with the current working directory if
- this is not an absolute path and there is no pre-specified hash value.
- Otherwise the inodes same will differ depending on whether a file is
- referenced with an absolute value or relatively. */
-
- if (!hash && !isabspath (name))
- {
- hash = cygheap->cwd.get_hash ();
- if (name[0] == '.' && name[1] == '\0')
- return hash;
- hash = '\\' + (hash << 6) + (hash << 16) - hash;
- }
+ /* Fill out the hashed path name with the current working directory if
+ this is not an absolute path and there is no pre-specified hash value.
+ Otherwise the inodes same will differ depending on whether a file is
+ referenced with an absolute value or relatively. */
+ if (!hash && !isabspath_u (name))
+ {
+ hash = cygheap->cwd.get_hash ();
+ if (name->Length == sizeof (WCHAR) && name->Buffer[0] == L'.')
+ return hash;
+ hash = L'\\' + (hash << 6) + (hash << 16) - hash;
}
hashit:
/* Build up hash. Name is already normalized */
- do
- {
- int ch = cyg_tolower (*name);
- hash = ch + (hash << 6) + (hash << 16) - hash;
- }
- while (*++name != '\0');
+ USHORT len = name->Length / sizeof (WCHAR);
+ for (USHORT idx = 0; idx < len; ++idx)
+ hash = RtlUpcaseUnicodeChar (name->Buffer[idx])
+ + (hash << 6) + (hash << 16) - hash;
return hash;
}
+__ino64_t __stdcall
+hash_path_name (__ino64_t hash, PCWSTR name)
+{
+ UNICODE_STRING uname;
+ RtlInitUnicodeString (&uname, name);
+ return hash_path_name (hash, &uname);
+}
+
+__ino64_t __stdcall
+hash_path_name (__ino64_t hash, const char *name)
+{
+ UNICODE_STRING uname;
+ RtlCreateUnicodeStringFromAsciiz (&uname, name);
+ __ino64_t ret = hash_path_name (hash, &uname);
+ RtlFreeUnicodeString (&uname);
+ return ret;
+}
+
char *
getcwd (char *buf, size_t ulen)
{
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 2d099304b..9e949e846 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -143,6 +143,12 @@ extern HANDLE tty_mutex;
type flag () const { return (type) status.flag; }
/* Used when treating / and \ as equivalent. */
+#define iswdirsep(ch) \
+ ({ \
+ WCHAR __c = (ch); \
+ ((__c) == L'/' || (__c) == L'\\'); \
+ })
+
#define isdirsep(ch) \
({ \
char __c = (ch); \
@@ -160,6 +166,18 @@ extern int __api_fatal_exit_val;
#undef issep
#define issep(ch) (strchr (" \t\n\r", (ch)) != NULL)
+/* Every path beginning with / or \, as well as every path being X:
+ or starting with X:/ or X:\ */
+#define isabspath_u(p) \
+ ((p)->Length && \
+ (iswdirsep ((p)->Buffer[0]) || \
+ ((p)->Length > sizeof (WCHAR) && iswalpha ((p)->Buffer[0]) \
+ && (p)->Buffer[1] == L':' && \
+ ((p)->Length == 2 * sizeof (WCHAR) || iswdirsep ((p)->Buffer[2])))))
+
+#define iswabspath(p) \
+ (iswdirsep (*(p)) || (iswalpha (*(p)) && (p)[1] == L':' && (!(p)[2] || iswdirsep ((p)[2]))))
+
#define isabspath(p) \
(isdirsep (*(p)) || (isalpha (*(p)) && (p)[1] == ':' && (!(p)[2] || isdirsep ((p)[2]))))
@@ -239,6 +257,8 @@ extern bool cygwin_finished_initializing;
void __stdcall set_std_handle (int);
int __stdcall stat_dev (DWORD, int, unsigned long, struct __stat64 *);
+__ino64_t __stdcall hash_path_name (__ino64_t hash, PUNICODE_STRING name) __attribute__ ((regparm(2)));
+__ino64_t __stdcall hash_path_name (__ino64_t hash, PCWSTR name) __attribute__ ((regparm(2)));
__ino64_t __stdcall hash_path_name (__ino64_t hash, const char *name) __attribute__ ((regparm(2)));
void __stdcall nofinalslash (const char *src, char *dst) __attribute__ ((regparm(2)));
extern "C" char *__stdcall rootdir (const char *full_path, char *root_path) __attribute__ ((regparm(2)));