OSDN Git Service

* fhandler_clipboard.cc: new file
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / path.cc
index cc33997..63a8efd 100644 (file)
@@ -62,7 +62,6 @@ details. */
 #include "cygerrno.h"
 #include "fhandler.h"
 #include "path.h"
-#include "thread.h"
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
@@ -70,6 +69,7 @@ details. */
 #include "shared_info.h"
 #include "registry.h"
 #include "security.h"
+#include <assert.h>
 
 static int normalize_win32_path (const char *src, char *dst);
 static void slashify (const char *src, char *dst, int trailing_slash_p);
@@ -190,6 +190,7 @@ path_conv::check (const char *src, unsigned opt,
   for (;;)
     {
       MALLOC_CHECK;
+      assert (src);
       char *p = strrchr (src, '/');
       if (p)
        {
@@ -430,6 +431,7 @@ const char *windows_device_names[] =
   "\\dev\\zero",
   "\\dev\\%srandom",
   "\\dev\\mem",
+  "\\dev\\clipboard",
 };
 
 static int
@@ -504,6 +506,8 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
           devn = FH_MEM;
           unit = 1;
         }
+      else if (deveq ("clipboard"))
+        devn = FH_CLIPBOARD;
       else if (deveq ("port"))
         {
           devn = FH_MEM;
@@ -572,15 +576,13 @@ normalize_posix_path (const char *src, char *dst)
     }
   if (!isslash (src[0]))
     {
-      char cwd[MAX_PATH];
-      if (!cygcwd.get (cwd))
+      if (!cygcwd.get (dst))
        return get_errno ();
-      if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
+      if (strlen (dst) + 1 + strlen (src) >= MAX_PATH)
        {
          debug_printf ("ENAMETOOLONG = normalize_posix_path (%s)", src);
          return ENAMETOOLONG;
        }
-      strcpy (dst, cwd);
       dst = strchr (dst, '\0');
       if (*src == '.')
        goto sawdot;
@@ -679,17 +681,15 @@ normalize_win32_path (const char *src, char *dst)
 
   if (!SLASH_P (src[0]) && strchr (src, ':') == NULL)
     {
-      char cwd[MAX_PATH];
-      if (!cygcwd.get (cwd, 0))
+      if (!cygcwd.get (dst, 0))
        return get_errno ();
-      if (strlen (cwd) + 1 + strlen (src) >= MAX_PATH)
+      if (strlen (dst) + 1 + strlen (src) >= MAX_PATH)
        {
          debug_printf ("ENAMETOOLONG = normalize_win32_path (%s)", src);
          return ENAMETOOLONG;
        }
-      strcpy (dst, cwd);
       dst += strlen (dst);
-      if (!*cwd || !SLASH_P (dst[-1]))
+      if (!SLASH_P (dst[-1]))
        *dst++ = '\\';
     }
   /* Two leading \'s?  If so, preserve them.  */
@@ -2163,6 +2163,7 @@ done:
 static __inline char *
 has_suffix (const char *path, const suffix_info *suffixes)
 {
+  assert (path);
   char *ext = strrchr (path, '.');
   if (ext)
     for (const suffix_info *ex = suffixes; ex->name != NULL; ex++)
@@ -2393,8 +2394,8 @@ hash_path_name (unsigned long hash, const char *name)
        {
          char *nn, *newname = (char *) alloca (strlen (name) + 2);
          nn = strncpy (newname, name, 2);
-         if (islower (*nn))
-           *newname = toupper (*nn);
+         if (isupper (*nn))
+           *newname = tolower (*nn);
          *(nn += 2) = '\0';
          name += 2;
          if (*name != '\\')
@@ -2412,12 +2413,12 @@ hash_path_name (unsigned long hash, const char *name)
         Otherwise the inodes same will differ depending on whether a file is
         referenced with an absolute value or relatively. */
 
-      if (*name != '\\')
+      if (!hash && !isabspath (name))
        {
          hash = cygcwd.get_hash ();
          if (name[0] == '.' && name[1] == '\0')
            return hash;
-         hash = hash_path_name (hash, "\\");
+         hash += hash_path_name (hash, "\\");
        }
     }
 
@@ -2426,7 +2427,8 @@ hashit:
      \a\b\.  but allow a single \ if that's all there is. */
   do
     {
-      hash += *name + (*name << 17);
+      int ch = tolower(*name);
+      hash += ch + (ch << 17);
       hash ^= hash >> 2;
     }
   while (*++name != '\0' &&
@@ -2771,7 +2773,7 @@ cygwin_split_path (const char *path, char *dir, char *file)
     })
 
 /* Return TRUE if two strings match up to length n */
-int __stdcall
+extern "C" int __stdcall
 strncasematch (const char *s1, const char *s2, size_t n)
 {
   if (s1 == s2)
@@ -2788,7 +2790,7 @@ strncasematch (const char *s1, const char *s2, size_t n)
 }
 
 /* Return TRUE if two strings match */
-int __stdcall
+extern "C" int __stdcall
 strcasematch (const char *s1, const char *s2)
 {
   if (s1 == s2)
@@ -2803,7 +2805,7 @@ strcasematch (const char *s1, const char *s2)
   return *s2 == '\0';
 }
 
-char * __stdcall
+extern "C" char * __stdcall
 strcasestr (const char *searchee, const char *lookfor)
 {
   if (*searchee == 0)
@@ -2877,10 +2879,11 @@ cwdstuff::fixup_after_exec (char *win32_cwd, char *posix_cwd, DWORD hash_cwd)
 bool
 cwdstuff::get_initial ()
 {
+  lock->acquire ();
+
   if (win32)
     return 1;
 
-  lock->acquire ();
   int i;
   DWORD len, dlen;
   for (i = 0, dlen = MAX_PATH, len = 0; i < 3; dlen *= 2, i++)
@@ -2895,6 +2898,7 @@ cwdstuff::get_initial ()
       __seterrno ();
       lock->release ();
       debug_printf ("get_initial_cwd failed, %E");
+      lock->release ();
       return 0;
     }
   set (NULL);
@@ -2937,6 +2941,13 @@ char *
 cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
 {
   MALLOC_CHECK;
+
+  if (ulen == 0)
+    {
+      set_errno (EINVAL);
+      goto out;
+    }
+
   if (!get_initial ()) /* Get initial cwd and set cwd lock */
     return NULL;
 
@@ -2955,7 +2966,7 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
     }
   else
     {
-      if (need_posix && !buf)
+      if (!buf)
        buf = (char *) malloc (strlen (tocopy) + 1);
       strcpy (buf, tocopy);
       if (!buf[0])     /* Should only happen when chroot */
@@ -2963,8 +2974,10 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
     }
 
   lock->release ();
-  syscall_printf ("(%s) = cwdstuff::get (%p, %d, %d, %d)",
-                 buf, buf, ulen, need_posix, with_chroot);
+
+out:
+  syscall_printf ("(%s) = cwdstuff::get (%p, %d, %d, %d), errno %d",
+                 buf, buf, ulen, need_posix, with_chroot, errno);
   MALLOC_CHECK;
   return buf;
 }