Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / lib / sh / pathcanon.c
index 41fc727..f19bd55 100644 (file)
@@ -1,42 +1,74 @@
-/* pathcanon.c -- Canonicalize and manipulate pathnames. */
+/* pathcanon.c -- canonicalize and manipulate pathnames. */
 
 /* Copyright (C) 2000 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
-   Bash is free software; you can redistribute it and/or modify it under
-   the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
+   Bash is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
-   WARRANTY; without even the implied warranty of MERCHANTABILITY or
-   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-   for more details.
+   Bash is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-   You should have received a copy of the GNU General Public License along
-   with Bash; see the file COPYING.  If not, write to the Free Software
-   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
-#include "config.h"
+#include <config.h>
 
-#include "bashtypes.h"
-#ifndef _MINIX
+#include <bashtypes.h>
+#if defined (HAVE_SYS_PARAM_H)
 #  include <sys/param.h>
 #endif
-#include "posixstat.h"
+#include <posixstat.h>
 
 #if defined (HAVE_UNISTD_H)
 #  include <unistd.h>
 #endif
 
-#include "filecntl.h"
-#include "bashansi.h"
+#include <filecntl.h>
+#include <bashansi.h>
 #include <stdio.h>
+#include <chartypes.h>
+#include <errno.h>
 
 #include "shell.h"
 
-#include "maxpath.h"
+#if !defined (errno)
+extern int errno;
+#endif
+
+#if defined (__CYGWIN__)
+#include <sys/cygwin.h>
+
+static int
+_is_cygdrive (path)
+     char *path;
+{
+  static char user[MAXPATHLEN];
+  static char system[MAXPATHLEN];
+  static int first_time = 1;
+
+  /* If the path is the first part of a network path, treat it as
+     existing. */
+  if (path[0] == '/' && path[1] == '/' && !strchr (path + 2, '/'))
+    return 1; 
+  /* Otherwise check for /cygdrive prefix. */
+  if (first_time)
+    {
+      char user_flags[MAXPATHLEN];
+      char system_flags[MAXPATHLEN];
+      /* Get the cygdrive info */
+      cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, system_flags);
+      first_time = 0;
+    }
+  return !strcasecmp (path, user) || !strcasecmp (path, system);
+}
+#endif /* __CYGWIN__ */        
 
 /* Return 1 if PATH corresponds to a directory.  A function for debugging. */
 static int
@@ -46,7 +78,13 @@ _path_isdir (path)
   int l;
   struct stat sb;
 
+  /* This should leave errno set to the correct value. */
+  errno = 0;
   l = stat (path, &sb) == 0 && S_ISDIR (sb.st_mode);
+#if defined (__CYGWIN__)
+  if (l == 0)
+    l = _is_cygdrive (path);
+#endif
   return l;
 }
 
@@ -80,7 +118,7 @@ sh_canonpath (path, flags)
     {
       stub_char = DIRSEP;
 #if defined (__CYGWIN__)
-      base = (isalpha(result[0]) && result[1] == ':') ? result + 3 : result + 1;
+      base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 3 : result + 1;
 #else
       base = result + 1;
 #endif
@@ -91,10 +129,11 @@ sh_canonpath (path, flags)
     {
       stub_char = '.';
 #if defined (__CYGWIN__)
-      base = (isalpha(result[0]) && result[1] == ':') ? result + 2 : result;
+      base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 2 : result;
 #else
       base = result;
 #endif
+      double_slash_path = 0;
     }
 
   /*