summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/path.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/path.cc')
-rw-r--r--winsup/cygwin/path.cc80
1 files changed, 35 insertions, 45 deletions
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)
{