OSDN Git Service

* winsup.h (NT_MAX_PATH): Revert ill-advised change to 32767.
authorcorinna <corinna>
Wed, 12 Mar 2008 12:41:46 +0000 (12:41 +0000)
committercorinna <corinna>
Wed, 12 Mar 2008 12:41:46 +0000 (12:41 +0000)
Accommodate change throughout.

* cygwin.din (cygwin_conv_path): Export.
(cygwin_conv_path_list): Export.
(cygwin_create_path): Export.
* dcrt0.cc (dll_crt0_1): Use cygwin_conv_path.
* dtable.cc (handle_to_fn): Ditto.  Don't expect UNICODE_STRING being
0-terminated.
* environ.cc (env_plist_to_posix): New helper function.
(env_plist_to_win32): Ditto.
(env_path_to_posix): Ditto.
(env_path_to_win32): Ditto.
(return_MAX_PATH): Remove.
(conv_envvars): Use new helper functions.  Drop removed members.
(win_env::operator =): Accommodate removal of path length functions.
(win_env::add_cache): Accommodate new env helper function API.
(posify): Ditto.
* environ.h (struct win_env): Ditto. Remove path length function
pointers since they are unused.
* path.cc (warn_msdos): Use cygwin_conv_path.
(getfileattr): Use new tmp_pathbuf::u_get method.
(fillout_mntent): Ditto.
(symlink_info::check): Ditto.
(path_conv::check): Use sizeof (WCHAR) instead of constant 2.
(symlink_info::check_reparse_point): Ditto.
(conv_path_list): Get max size of target string as argument.  Call
cygwin_conv_path as helper function.
(cygwin_conv_path): New function.
(cygwin_create_path): New function.
(cygwin_conv_to_win32_path): Just call cygwin_conv_path with size set
to MAX_PATH.
(cygwin_conv_to_full_win32_path): Ditto.
(cygwin_conv_to_posix_path): Ditto.
(cygwin_conv_to_full_posix_path): Ditto.
(conv_path_list_buf_size): Add FIXME comment.
(env_PATH_to_posix): Rename from env_win32_to_posix_path_list.
Add size argument as required for env helper functions.
(cygwin_win32_to_posix_path_list): Call conv_path_list with size set to
MAX_PATH.
(cygwin_posix_to_win32_path_list): Ditto.
(cygwin_conv_path_list): New function.
(cwdstuff::get): Fix length argument in call to sys_wcstombs.
* spawn.cc (find_exec): Use cygwin_conv_path_list.
* tls_pbuf.h (tmp_pathbuf::u_get: New method.
* uinfo.cc (cygheap_user::ontherange): Allocate temporary path buffers
using tmp_pathbuf.  Use cygwin_conv_path.
* winf.cc (av::unshift): Use cygwin_conv_path.
* include/cygwin/version.h: Bump API minor number.
* include/sys/cygwin.h: Comment out old cygwin32_XXX API.
Mark old path handling API as deprecated.
(cygwin_conv_path_t): Typedef.  Define values.
(cygwin_conv_path): Declare.
(cygwin_create_path): Declare.
(cygwin_conv_path_list): Declare.

17 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/cygtls.cc
winsup/cygwin/cygwin.din
winsup/cygwin/dcrt0.cc
winsup/cygwin/dtable.cc
winsup/cygwin/environ.cc
winsup/cygwin/environ.h
winsup/cygwin/exceptions.cc
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/path.cc
winsup/cygwin/spawn.cc
winsup/cygwin/tls_pbuf.cc
winsup/cygwin/tls_pbuf.h
winsup/cygwin/uinfo.cc
winsup/cygwin/winf.cc
winsup/cygwin/winsup.h

index d0be794..85ffa11 100644 (file)
@@ -1,3 +1,61 @@
+2008-03-12  Corinna Vinschen  <corinna@vinschen.de>
+
+       * winsup.h (NT_MAX_PATH): Revert ill-advised change to 32767.
+       Accommodate change throughout.
+
+       * cygwin.din (cygwin_conv_path): Export.
+       (cygwin_conv_path_list): Export.
+       (cygwin_create_path): Export.
+       * dcrt0.cc (dll_crt0_1): Use cygwin_conv_path.
+       * dtable.cc (handle_to_fn): Ditto.  Don't expect UNICODE_STRING being
+       0-terminated.
+       * environ.cc (env_plist_to_posix): New helper function.
+       (env_plist_to_win32): Ditto.
+       (env_path_to_posix): Ditto.
+       (env_path_to_win32): Ditto.
+       (return_MAX_PATH): Remove.
+       (conv_envvars): Use new helper functions.  Drop removed members.
+       (win_env::operator =): Accommodate removal of path length functions.
+       (win_env::add_cache): Accommodate new env helper function API.
+       (posify): Ditto.
+       * environ.h (struct win_env): Ditto. Remove path length function
+       pointers since they are unused.
+       * path.cc (warn_msdos): Use cygwin_conv_path.
+       (getfileattr): Use new tmp_pathbuf::u_get method.
+       (fillout_mntent): Ditto.
+       (symlink_info::check): Ditto.
+       (path_conv::check): Use sizeof (WCHAR) instead of constant 2.
+       (symlink_info::check_reparse_point): Ditto.
+       (conv_path_list): Get max size of target string as argument.  Call
+       cygwin_conv_path as helper function.
+       (cygwin_conv_path): New function.
+       (cygwin_create_path): New function.
+       (cygwin_conv_to_win32_path): Just call cygwin_conv_path with size set
+       to MAX_PATH.
+       (cygwin_conv_to_full_win32_path): Ditto.
+       (cygwin_conv_to_posix_path): Ditto.
+       (cygwin_conv_to_full_posix_path): Ditto.
+       (conv_path_list_buf_size): Add FIXME comment.
+       (env_PATH_to_posix): Rename from env_win32_to_posix_path_list.
+       Add size argument as required for env helper functions.
+       (cygwin_win32_to_posix_path_list): Call conv_path_list with size set to
+       MAX_PATH.
+       (cygwin_posix_to_win32_path_list): Ditto.
+       (cygwin_conv_path_list): New function.
+       (cwdstuff::get): Fix length argument in call to sys_wcstombs.
+       * spawn.cc (find_exec): Use cygwin_conv_path_list.
+       * tls_pbuf.h (tmp_pathbuf::u_get: New method.
+       * uinfo.cc (cygheap_user::ontherange): Allocate temporary path buffers
+       using tmp_pathbuf.  Use cygwin_conv_path.
+       * winf.cc (av::unshift): Use cygwin_conv_path.
+       * include/cygwin/version.h: Bump API minor number.
+       * include/sys/cygwin.h: Comment out old cygwin32_XXX API.
+       Mark old path handling API as deprecated.
+       (cygwin_conv_path_t): Typedef.  Define values.
+       (cygwin_conv_path): Declare.
+       (cygwin_create_path): Declare.
+       (cygwin_conv_path_list): Declare.
+
 2008-03-11  Corinna Vinschen  <corinna@vinschen.de>
 
        * dlfcn.cc (get_full_path_of_dll): Allow paths up to PATH_MAX.
index 749af01..8769a6a 100644 (file)
@@ -249,18 +249,6 @@ _cygtls::init_exception_handler (exception_handler *eh)
      Windows 2008, which irremediably gets into an endless loop, taking 100%
      CPU.  That's why we reverted to a normal SEH chain and changed the way
      the exception handler returns to the application. */
-  /* 2008-03-28 - The fun continues.  Revert to doing something sorta like
-     before.  Just make sure *only* the cygwin exception handler is installed
-     rather than honoring other exception handlers.  The theory here is that
-     cygwin should be in control and there should be no Windows voodoo going
-     on behind the scenes.
-
-     This change was made so that this function could be called from
-     handle_exceptions to essentially "clean up" the exception handling
-     linked list.
-
-     The open question is whether making this NULL will have an adverse effect
-     on Windows functions. */
+  el.prev = _except_list;
   _except_list = &el;
-  el.prev = NULL;
 }
index da6b986..c57629c 100644 (file)
@@ -237,10 +237,13 @@ cygwin32_win32_to_posix_path_list = cygwin_win32_to_posix_path_list SIGFE
 cygwin32_win32_to_posix_path_list_buf_size = cygwin_win32_to_posix_path_list_buf_size SIGFE
 cygwin32_winpid_to_pid = cygwin_winpid_to_pid SIGFE
 cygwin_attach_handle_to_fd SIGFE
+cygwin_conv_path SIGFE
+cygwin_conv_path_list SIGFE
 cygwin_conv_to_full_posix_path SIGFE
 cygwin_conv_to_full_win32_path SIGFE
 cygwin_conv_to_posix_path SIGFE
 cygwin_conv_to_win32_path SIGFE
+cygwin_create_path SIGFE
 cygwin_detach_dll SIGFE_MAYBE
 cygwin_dll_init NOSIGFE
 cygwin_internal NOSIGFE
index 7468fe0..ac42aaa 100644 (file)
@@ -859,7 +859,8 @@ dll_crt0_1 (void *)
       if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\')))
        {
          char *new_argv0 = (char *) malloc (NT_MAX_PATH);
-         cygwin_conv_to_posix_path (__argv[0], new_argv0);
+         cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, __argv[0],
+                           new_argv0, NT_MAX_PATH);
          __argv[0] = (char *) realloc (new_argv0, strlen (new_argv0) + 1);
        }
     }
index 7cf4136..f1eb20f 100644 (file)
@@ -854,7 +854,7 @@ handle_to_fn (HANDLE h, char *posix_fn)
 
   memset (fnbuf, 0, len);
   ntfn = (OBJECT_NAME_INFORMATION *) fnbuf;
-  ntfn->Name.MaximumLength = NT_MAX_PATH * sizeof (WCHAR);
+  ntfn->Name.MaximumLength = (NT_MAX_PATH - 1) * sizeof (WCHAR);
   ntfn->Name.Buffer = (WCHAR *) (ntfn + 1);
 
   NTSTATUS res = NtQueryObject (h, ObjectNameInformation, ntfn, len, NULL);
@@ -876,7 +876,8 @@ handle_to_fn (HANDLE h, char *posix_fn)
   ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = 0;
 
   char *win32_fn = tp.c_get ();
-  sys_wcstombs (win32_fn, NT_MAX_PATH, ntfn->Name.Buffer);
+  sys_wcstombs (win32_fn, NT_MAX_PATH, ntfn->Name.Buffer,
+               ntfn->Name.Length / sizeof (WCHAR));
   debug_printf ("nt name '%s'", win32_fn);
   if (!strncasematch (win32_fn, DEVICE_PREFIX, DEVICE_PREFIX_LEN)
       || !QueryDosDevice (NULL, fnbuf, len))
@@ -947,7 +948,8 @@ handle_to_fn (HANDLE h, char *posix_fn)
     }
 
   if (!justslash)
-    cygwin_conv_to_full_posix_path (w32, posix_fn);
+    cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, w32, posix_fn,
+                     NT_MAX_PATH);
   else
     {
       char *s, *d;
index 76c6820..514aa5c 100644 (file)
@@ -47,7 +47,37 @@ extern bool allow_server;
 
 static char **lastenviron;
 
-extern "C" int env_win32_to_posix_path_list (const char *, char *posix);
+/* Helper functions for the below environment variables which have to
+   be converted Win32<->POSIX. */
+extern "C" ssize_t env_PATH_to_posix (const void *, void *, size_t);
+
+ssize_t
+env_plist_to_posix (const void *win32, void *posix, size_t size)
+{
+  return cygwin_conv_path_list (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, win32,
+                               posix, size);
+}
+
+ssize_t
+env_plist_to_win32 (const void *posix, void *win32, size_t size)
+{
+  return cygwin_conv_path_list (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, posix,
+                               win32, size);
+}
+
+ssize_t
+env_path_to_posix (const void *win32, void *posix, size_t size)
+{
+  return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, win32,
+                          posix, size);
+}
+
+ssize_t
+env_path_to_win32 (const void *posix, void *win32, size_t size)
+{
+  return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, posix,
+                          win32, size);
+}
 
 #define ENVMALLOC \
   (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) \
@@ -60,26 +90,16 @@ extern "C" int env_win32_to_posix_path_list (const char *, char *posix);
    PATH needs to be here because CreateProcess uses it and gdb uses
    CreateProcess.  HOME is here because most shells use it and would be
    confused by Windows style path names.  */
-static int return_MAX_PATH (const char *) {return CYG_MAX_PATH;}
 static win_env conv_envvars[] =
   {
-    {NL ("PATH="), NULL, NULL, env_win32_to_posix_path_list,
-     cygwin_posix_to_win32_path_list,
-     cygwin_win32_to_posix_path_list_buf_size,
-     cygwin_posix_to_win32_path_list_buf_size, true},
-    {NL ("HOME="), NULL, NULL, cygwin_conv_to_full_posix_path,
-     cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
-    {NL ("LD_LIBRARY_PATH="), NULL, NULL, cygwin_win32_to_posix_path_list,
-     cygwin_posix_to_win32_path_list,
-     cygwin_win32_to_posix_path_list_buf_size,
-     cygwin_posix_to_win32_path_list_buf_size, true},
-    {NL ("TMPDIR="), NULL, NULL, cygwin_conv_to_full_posix_path,
-     cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
-    {NL ("TMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
-     cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
-    {NL ("TEMP="), NULL, NULL, cygwin_conv_to_full_posix_path,
-     cygwin_conv_to_full_win32_path, return_MAX_PATH, return_MAX_PATH, false},
-    {NULL, 0, NULL, NULL, NULL, NULL, 0, 0}
+    {NL ("PATH="), NULL, NULL, env_PATH_to_posix, env_plist_to_win32, true},
+    {NL ("HOME="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
+    {NL ("LD_LIBRARY_PATH="), NULL, NULL,
+                              env_plist_to_posix, env_plist_to_win32, true},
+    {NL ("TMPDIR="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
+    {NL ("TMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
+    {NL ("TEMP="), NULL, NULL, env_path_to_posix, env_path_to_win32, false},
+    {NULL, 0, NULL, NULL, 0, 0}
   };
 
 static unsigned char conv_start_chars[256] = {0};
@@ -91,8 +111,6 @@ win_env::operator = (struct win_env& x)
   namelen = x.namelen;
   toposix = x.toposix;
   towin32 = x.towin32;
-  posix_len = x.posix_len;
-  win32_len = x.win32_len;
   immediate = false;
   return *this;
 }
@@ -122,7 +140,7 @@ win_env::add_cache (const char *in_posix, const char *in_native)
       tmp_pathbuf tp;
       char *buf = tp.c_get ();
       strcpy (buf, name + namelen);
-      towin32 (in_posix, buf);
+      towin32 (in_posix, buf, NT_MAX_PATH);
       native = (char *) realloc (native, namelen + 1 + strlen (buf));
       strcpy (native, name);
       strcpy (native + namelen, buf);
@@ -191,14 +209,15 @@ posify (char **here, const char *value, char *outenv)
 
   memcpy (outenv, src, len);
   char *newvalue = outenv + len;
-  if (!conv->toposix (value, newvalue) || _impure_ptr->_errno != EIDRM)
+  if (!conv->toposix (value, newvalue, NT_MAX_PATH - len)
+      || _impure_ptr->_errno != EIDRM)
     conv->add_cache (newvalue, *value != '/' ? value : NULL);
   else
     {
       /* The conversion routine removed elements from a path list so we have
         to recalculate the windows path to remove elements there, too. */
       char cleanvalue[strlen (value) + 1];
-      conv->towin32 (newvalue, cleanvalue);
+      conv->towin32 (newvalue, cleanvalue, sizeof cleanvalue);
       conv->add_cache (newvalue, cleanvalue);
     }
 
index c2c29cf..a50ef5b 100644 (file)
@@ -23,10 +23,8 @@ struct win_env
     size_t namelen;
     char *posix;
     char *native;
-    int (*toposix) (const char *, char *);
-    int (*towin32) (const char *, char *);
-    int (*posix_len) (const char *);
-    int (*win32_len) (const char *);
+    ssize_t (*toposix) (const void *, void *, size_t);
+    ssize_t (*towin32) (const void *, void *, size_t);
     bool immediate;
     void add_cache (const char *in_posix, const char *in_native = NULL)
       __attribute__ ((regparm (3)));
index 71c15d5..6eb1715 100644 (file)
@@ -470,6 +470,8 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
 
 /* Main exception handler. */
 
+extern exception_list *_except_list asm ("%fs:0");
+
 extern "C" char *__progname;
 int
 _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
@@ -623,9 +625,10 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
 
   me.copy_context (in);
 
-  /* Reinitialize exception handler list to include just ourselves so that any
-     exceptions that occur in a signal handler will be properly caught. */
-  me.init_exception_handler (handle_exceptions);
+  /* Temporarily replace windows top level SEH with our own handler.
+     We don't want any Windows magic kicking in.  This top level frame
+     will be removed automatically after our exception handler returns. */
+  _except_list->handler = _cygtls::handle_exceptions;
 
   if (masked
       || &me == _sig_tls
@@ -634,7 +637,6 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
       || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
       || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
     {
-      rtl_unwind (frame, e);
       /* Print the exception to the console */
       if (!myself->cygstarted)
        for (int i = 0; status_info[i].name; i++)
@@ -656,6 +658,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
              return 0;
            }
 
+         rtl_unwind (frame, e);
          open_stackdumpfile ();
          exception (e, in);
          stackdump ((DWORD) ebp, 0, 1);
index da6f3ce..afad4be 100644 (file)
@@ -323,12 +323,13 @@ details. */
       180: Export getxattr, lgetxattr, fgetxattr, listxattr, llistxattr,
           flistxattr, setxattr, lsetxattr, fsetxattr, removexattr,
           lremovexattr, fremovexattr.
+      181: Export cygwin_conv_path, cygwin_create_path, cygwin_conv_path_list.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 180
+#define CYGWIN_VERSION_API_MINOR 181
 
      /* There is also a compatibity version number associated with the
        shared memory regions.  It is incremented when incompatible
index 51247e5..26daf0f 100644 (file)
@@ -20,6 +20,7 @@ extern "C" {
 
 #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
 
+#if 0 /* ENTIRELY DEPRECATED INTERFACES. */
 extern pid_t cygwin32_winpid_to_pid (int);
 extern void cygwin32_win32_to_posix_path_list (const char *, char *);
 extern int cygwin32_win32_to_posix_path_list_buf_size (const char *);
@@ -31,16 +32,64 @@ extern void cygwin32_conv_to_posix_path (const char *, char *);
 extern void cygwin32_conv_to_full_posix_path (const char *, char *);
 extern int cygwin32_posix_path_list_p (const char *);
 extern void cygwin32_split_path (const char *, char *, char *);
+#endif
+
+/* DEPRECATED INTERFACES.  These are restricted to MAX_PATH length.
+   Don't use in modern applications. */
+extern int cygwin_win32_to_posix_path_list (const char *, char *)
+  __attribute__ ((deprecated));
+extern int cygwin_win32_to_posix_path_list_buf_size (const char *)
+  __attribute__ ((deprecated));
+extern int cygwin_posix_to_win32_path_list (const char *, char *)
+  __attribute__ ((deprecated));
+extern int cygwin_posix_to_win32_path_list_buf_size (const char *)
+  __attribute__ ((deprecated));
+extern int cygwin_conv_to_win32_path (const char *, char *)
+  __attribute__ ((deprecated));
+extern int cygwin_conv_to_full_win32_path (const char *, char *)
+  __attribute__ ((deprecated));
+extern int cygwin_conv_to_posix_path (const char *, char *)
+  __attribute__ ((deprecated));
+extern int cygwin_conv_to_full_posix_path (const char *, char *)
+  __attribute__ ((deprecated));
+
+/* Use these interfaces in favor of the above. */
+
+/* Possible 'what' values in calls to cygwin_conv_path/cygwin_create_path. */
+enum
+{
+  CCP_POSIX_TO_WIN_A = 0, /* from is char*, to is char*       */
+  CCP_POSIX_TO_WIN_W,    /* from is char*, to is wchar_t*    */
+  CCP_WIN_A_TO_POSIX,    /* from is char*, to is char*       */
+  CCP_WIN_W_TO_POSIX,    /* from is wchar_t*, to is char*    */
+
+  /* Or these values to the above as needed. */
+  CCP_ABSOLUTE = 0,      /* Request absolute path (default). */
+  CCP_RELATIVE = 0x100    /* Request to keep path relative.   */
+};
+typedef unsigned int cygwin_conv_path_t;
+
+/* If size is 0, cygwin_conv_path returns the required buffer size in bytes.
+   Otherwise, it returns 0 on success, or -1 on error and errno is set to
+   one of the below values:
+
+    EINVAL        what has an invalid value.
+    EFAULT        from or to point into nirvana.
+    ENAMETOOLONG  the resulting path is longer than 32K, or, in case
+                 of what == CCP_POSIX_TO_WIN_A, longer than MAX_PATH.
+    ENOSPC        size is less than required for the conversion.
+*/
+extern ssize_t cygwin_conv_path (cygwin_conv_path_t what, const void *from,
+                                void *to, size_t size);
+/* Same, but handles path lists separated by colon or semicolon. */
+extern ssize_t cygwin_conv_path_list (cygwin_conv_path_t what, const void *from,
+                                void *to, size_t size);
+/* Allocate a buffer for the conversion result using malloc(3), and return
+   a pointer to it.  Returns NULL if something goes wrong with errno set
+   to one of the above values, or to ENOMEM if malloc fails. */
+extern void *cygwin_create_path (cygwin_conv_path_t what, const void *from);
 
 extern pid_t cygwin_winpid_to_pid (int);
-extern int cygwin_win32_to_posix_path_list (const char *, char *);
-extern int cygwin_win32_to_posix_path_list_buf_size (const char *);
-extern int cygwin_posix_to_win32_path_list (const char *, char *);
-extern int cygwin_posix_to_win32_path_list_buf_size (const char *);
-extern int cygwin_conv_to_win32_path (const char *, char *);
-extern int cygwin_conv_to_full_win32_path (const char *, char *);
-extern int cygwin_conv_to_posix_path (const char *, char *);
-extern int cygwin_conv_to_full_posix_path (const char *, char *);
 extern int cygwin_posix_path_list_p (const char *);
 extern void cygwin_split_path (const char *, char *, char *);
 
index 1ddf9cd..af6b06c 100644 (file)
@@ -652,7 +652,8 @@ warn_msdos (const char *src)
   tmp_pathbuf tp;
   char *posix_path = tp.c_get ();
   small_printf ("cygwin warning:\n");
-  if (cygwin_conv_to_full_posix_path (src, posix_path))
+  if (cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, src,
+                       posix_path, NT_MAX_PATH))
     small_printf ("  MS-DOS style path detected: %s\n  POSIX equivalent preferred.\n",
                  src);
   else
@@ -661,7 +662,6 @@ warn_msdos (const char *src)
   small_printf ("  CYGWIN environment variable option \"nodosfilewarning\" turns off this warning.\n"
                "  Consult the user's guide for more details about POSIX paths:\n"
                "    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames\n");
-
   user_shared->warned_msdos = true;
 }
 
@@ -675,7 +675,7 @@ getfileattr (const char *path) /* path has to be always absolute. */
   NTSTATUS status;
   IO_STATUS_BLOCK io;
 
-  RtlInitEmptyUnicodeString (&upath, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
+  tp.u_get (&upath);
   InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
   get_nt_native_path (path, upath);
 
@@ -742,7 +742,7 @@ path_conv::check (PUNICODE_STRING src, unsigned opt,
   char *path = tp.c_get ();
 
   user_shared->warned_msdos = true;
-  sys_wcstombs (path, NT_MAX_PATH, src->Buffer, src->Length / 2);
+  sys_wcstombs (path, NT_MAX_PATH, src->Buffer, src->Length / sizeof (WCHAR));
   path_conv::check (path, opt, suffixes);
 }
 
@@ -1504,22 +1504,22 @@ nofinalslash (const char *src, char *dst)
 /* conv_path_list: Convert a list of path names to/from Win32/POSIX. */
 
 static int
-conv_path_list (const char *src, char *dst, int to_posix)
+conv_path_list (const char *src, char *dst, size_t size, int to_posix)
 {
   char src_delim, dst_delim;
-  int (*conv_fn) (const char *, char *);
+  cygwin_conv_path_t conv_fn;
 
   if (to_posix)
     {
       src_delim = ';';
       dst_delim = ':';
-      conv_fn = cygwin_conv_to_posix_path;
+      conv_fn = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
     }
   else
     {
       src_delim = ':';
       dst_delim = ';';
-      conv_fn = cygwin_conv_to_win32_path;
+      conv_fn = CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
     }
 
   char *srcbuf = (char *) alloca (strlen (src) + 1);
@@ -1530,16 +1530,22 @@ conv_path_list (const char *src, char *dst, int to_posix)
   do
     {
       char *s = strccpy (srcbuf, &src, src_delim);
-      int len = s - srcbuf;
+      size_t len = s - srcbuf;
       if (len >= NT_MAX_PATH)
        {
          err = ENAMETOOLONG;
          break;
        }
       if (len)
-       err = conv_fn (srcbuf, ++d);
+       {
+         ++d;
+         err = cygwin_conv_path (conv_fn, srcbuf, d, size - (d - dst));
+        }
       else if (!to_posix)
-       err = conv_fn (".", ++d);
+       {
+         ++d;
+         err = cygwin_conv_path (conv_fn, ".", d, size - (d - dst));
+       }
       else
        {
          if (to_posix == ENV_CVT)
@@ -2767,7 +2773,7 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
   fs_info mntinfo;
   tmp_pathbuf tp;
   UNICODE_STRING unat;
-  RtlInitEmptyUnicodeString (&unat, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
+  tp.u_get (&unat);
   get_nt_native_path (native_path, unat);
   if (append_bs)
     RtlAppendUnicodeToString (&unat, L"\\");
@@ -3431,7 +3437,7 @@ symlink_info::check_reparse_point (HANDLE h)
       sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
                    (WCHAR *)((char *)rp->SymbolicLinkReparseBuffer.PathBuffer
                          + rp->SymbolicLinkReparseBuffer.SubstituteNameOffset),
-                   rp->SymbolicLinkReparseBuffer.SubstituteNameLength / 2);
+                   rp->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof (WCHAR));
       pflags = PATH_SYMLINK | PATH_REP;
       fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
     }
@@ -3445,7 +3451,7 @@ symlink_info::check_reparse_point (HANDLE h)
       sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
                    (WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
                            + rp->MountPointReparseBuffer.SubstituteNameOffset),
-                   rp->MountPointReparseBuffer.SubstituteNameLength / 2);
+                   rp->MountPointReparseBuffer.SubstituteNameLength / sizeof (WCHAR));
       pflags = PATH_SYMLINK | PATH_REP;
       fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
     }
@@ -3724,7 +3730,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt)
   tmp_pathbuf tp;
   UNICODE_STRING upath;
   OBJECT_ATTRIBUTES attr;
-  RtlInitEmptyUnicodeString (&upath, tp.w_get (), NT_MAX_PATH * sizeof (WCHAR));
+  tp.u_get (&upath);
   InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
 
   while (suffix.next ())
@@ -4154,36 +4160,114 @@ fchdir (int fd)
     return -1;\
   } while (0)
 
-extern "C" int
-cygwin_conv_to_win32_path (const char *path, char *win32_path)
+extern "C" ssize_t
+cygwin_conv_path (cygwin_conv_path_t what, const void *from, void *to,
+                 size_t size)
 {
-  path_conv p (path, PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOFULL | PC_NOWARN);
-  if (p.error)
+  myfault efault;
+  if (efault.faulted (EFAULT))
+    return -1;
+
+  path_conv p;
+  tmp_pathbuf tp;
+  size_t lsiz = 0;
+  char *buf = NULL;
+  int error = 0;
+  bool relative = !!(what & CCP_RELATIVE);
+  what &= ~CCP_RELATIVE;
+
+  switch (what)
+    {
+    case CCP_POSIX_TO_WIN_A:
+      p.check ((const char *) from,
+              PC_POSIX | PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN
+              | (relative ? PC_NOFULL : 0));
+      if (p.error)
+       return_with_errno (p.error);
+      PUNICODE_STRING up = p.get_nt_native_path ();
+      buf = tp.c_get ();
+      sys_wcstombs (buf, NT_MAX_PATH, up->Buffer, up->Length / sizeof (WCHAR));
+      buf += 4; /* Skip \??\ */
+      if (ascii_strncasematch (buf, "UNC\\", 4))
+       *(buf += 2) = '\\';
+      lsiz = strlen (buf) + 1;
+      break;
+    case CCP_POSIX_TO_WIN_W:
+      p.check ((const char *) from,
+              PC_POSIX | PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN
+              | (relative ? PC_NOFULL : 0));
+      if (p.error)
+       return_with_errno (p.error);
+      lsiz = (p.get_wide_win32_path_len () + 1) * sizeof (WCHAR);
+      break;
+    case CCP_WIN_A_TO_POSIX:
+      buf = tp.c_get ();
+      error = mount_table->conv_to_posix_path ((const char *) from, buf,
+                                              relative);
+      if (error)
+       return_with_errno (error);
+      lsiz = strlen (buf) + 1;
+      break;
+    case CCP_WIN_W_TO_POSIX:
+      buf = tp.c_get ();
+      error = mount_table->conv_to_posix_path ((const PWCHAR) from, buf,
+                                              relative);
+      if (error)
+       return_with_errno (error);
+      lsiz = strlen (buf) + 1;
+      break;
+    default:
+      set_errno (EINVAL);
+      return -1;
+    }
+  if (!size)
+    return lsiz;
+  if (size < lsiz)
     {
-      win32_path[0] = '\0';
-      set_errno (p.error);
+      set_errno (ENOSPC);
       return -1;
     }
+  switch (what)
+    {
+    case CCP_POSIX_TO_WIN_A:
+    case CCP_WIN_A_TO_POSIX:
+    case CCP_WIN_W_TO_POSIX:
+      strcpy ((char *) to, buf);
+      break;
+    case CCP_POSIX_TO_WIN_W:
+      p.get_wide_win32_path ((PWCHAR) to);
+      break;
+    }
+  return 0;
+}
+
+extern "C" void *
+cygwin_create_path (cygwin_conv_path_t what, const void *from)
+{
+  void *to;
+  ssize_t size = cygwin_conv_path (what, from, NULL, 0);
+  if (size <= 0)
+    return NULL;
+  if (!(to = malloc (size)))
+    return NULL;
+  if (cygwin_conv_path (what, from, to, size) == -1)
+    return NULL;
+  return to;
+}
 
 
-  strcpy (win32_path,
-         strcmp (p.get_win32 (), ".\\") == 0 ? "." : p.get_win32 ());
-  return 0;
+extern "C" int
+cygwin_conv_to_win32_path (const char *path, char *win32_path)
+{
+  return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_RELATIVE, path, win32_path,
+                          MAX_PATH);
 }
 
 extern "C" int
 cygwin_conv_to_full_win32_path (const char *path, char *win32_path)
 {
-  path_conv p (path, PC_SYM_FOLLOW | PC_NO_ACCESS_CHECK | PC_NOWARN);
-  if (p.error)
-    {
-      win32_path[0] = '\0';
-      set_errno (p.error);
-      return -1;
-    }
-
-  strcpy (win32_path, p.get_win32 ());
-  return 0;
+  return cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE, path, win32_path,
+                          MAX_PATH);
 }
 
 /* This is exported to the world as cygwin_foo by cygwin.din.  */
@@ -4191,29 +4275,15 @@ cygwin_conv_to_full_win32_path (const char *path, char *win32_path)
 extern "C" int
 cygwin_conv_to_posix_path (const char *path, char *posix_path)
 {
-  myfault efault;
-  if (efault.faulted (EFAULT))
-    return -1;
-  if (!*path)
-    {
-      set_errno (ENOENT);
-      return -1;
-    }
-  return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 1));
+  return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, path, posix_path,
+                          MAX_PATH);
 }
 
 extern "C" int
 cygwin_conv_to_full_posix_path (const char *path, char *posix_path)
 {
-  myfault efault;
-  if (efault.faulted (EFAULT))
-    return -1;
-  if (!*path)
-    {
-      set_errno (ENOENT);
-      return -1;
-    }
-  return_with_errno (mount_table->conv_to_posix_path (path, posix_path, 0));
+  return cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, path, posix_path,
+                          MAX_PATH);
 }
 
 /* The realpath function is supported on some UNIX systems.  */
@@ -4322,6 +4392,7 @@ conv_path_list_buf_size (const char *path_list, bool to_posix)
   path_conv pc(".", PC_POSIX);
   /* The theory is that an upper bound is
      current_size + (num_elms * max_mount_path_len)  */
+  /* FIXME: This method is questionable in the long run. */
 
   unsigned nrel;
   char delim = to_posix ? ';' : ':';
@@ -4365,22 +4436,51 @@ cygwin_posix_to_win32_path_list_buf_size (const char *path_list)
   return conv_path_list_buf_size (path_list, false);
 }
 
-extern "C" int
-env_win32_to_posix_path_list (const char *win32, char *posix)
+extern "C" ssize_t
+env_PATH_to_posix (const void *win32, void *posix, size_t size)
 {
-  return_with_errno (conv_path_list (win32, posix, ENV_CVT));
+  return_with_errno (conv_path_list ((const char *) win32, (char *) posix,
+                                    size, ENV_CVT));
 }
 
 extern "C" int
 cygwin_win32_to_posix_path_list (const char *win32, char *posix)
 {
-  return_with_errno (conv_path_list (win32, posix, 1));
+  return_with_errno (conv_path_list (win32, posix, MAX_PATH, 1));
 }
 
 extern "C" int
 cygwin_posix_to_win32_path_list (const char *posix, char *win32)
 {
-  return_with_errno (conv_path_list (posix, win32, 0));
+  return_with_errno (conv_path_list (posix, win32, MAX_PATH, 0));
+}
+
+extern "C" ssize_t
+cygwin_conv_path_list (cygwin_conv_path_t what, const void *from, void *to,
+                      size_t size)
+{
+  /* FIXME: Path lists are (so far) always retaining relative paths. */
+  what &= ~CCP_RELATIVE;
+  switch (what)
+    {
+    case CCP_WIN_W_TO_POSIX:
+    case CCP_POSIX_TO_WIN_W:
+      /*FIXME*/
+      api_fatal ("wide char path lists not yet supported");
+      break;
+    case CCP_WIN_A_TO_POSIX:
+    case CCP_POSIX_TO_WIN_A:
+      if (size == 0)
+       return conv_path_list_buf_size ((const char *) from,
+                                       what == CCP_WIN_A_TO_POSIX);
+      return_with_errno (conv_path_list ((const char *) from, (char *) to,
+                                        size, what == CCP_WIN_A_TO_POSIX));
+      break;
+    default:
+      break;
+    }
+  set_errno (EINVAL);
+  return -1;
 }
 
 /* cygwin_split_path: Split a path into directory and file name parts.
@@ -4685,7 +4785,8 @@ cwdstuff::get (char *buf, int need_posix, int with_chroot, unsigned ulen)
   if (!need_posix)
     {
       tocopy = tp.c_get ();
-      sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer, win32.Length);
+      sys_wcstombs (tocopy, NT_MAX_PATH, win32.Buffer,
+                   win32.Length / sizeof (WCHAR));
     }
   else
     tocopy = posix;
index 79b0494..cb5af80 100644 (file)
@@ -138,9 +138,9 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv,
   if (strchr (mywinenv, '/'))
     {
       /* it's not really an environment variable at all */
-      int n = cygwin_posix_to_win32_path_list_buf_size (mywinenv);
-      char *s = (char *) alloca (n + 1);
-      if (cygwin_posix_to_win32_path_list (mywinenv, s))
+      int n = cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, NULL, 0);
+      char *s = (char *) alloca (n);
+      if (cygwin_conv_path_list (CCP_POSIX_TO_WIN_A, mywinenv, s, n))
        goto errout;
       path = s;
       posix_path = mywinenv - 1;
index 802885e..704f3bf 100644 (file)
@@ -42,7 +42,7 @@ tmp_pathbuf::c_get ()
   if (tls_pbuf.c_cnt >= TP_NUM_C_BUFS)
     api_fatal ("Internal error: TP_NUM_C_BUFS too small.");
   if (!tls_pbuf.c_buf[tls_pbuf.c_cnt]
-      && !(tls_pbuf.c_buf[tls_pbuf.c_cnt] = (char *) malloc (NT_MAX_PATH + 1)))
+      && !(tls_pbuf.c_buf[tls_pbuf.c_cnt] = (char *) malloc (NT_MAX_PATH)))
     api_fatal ("Internal error: Out of memory for new path buf.");
   return tls_pbuf.c_buf[tls_pbuf.c_cnt++];
 }
@@ -54,7 +54,7 @@ tmp_pathbuf::w_get ()
     api_fatal ("Internal error: TP_NUM_W_BUFS too small.");
   if (!tls_pbuf.w_buf[tls_pbuf.w_cnt]
       && !(tls_pbuf.w_buf[tls_pbuf.w_cnt]
-          = (PWCHAR) malloc ((NT_MAX_PATH + 1) * sizeof (WCHAR))))
+          = (PWCHAR) malloc (NT_MAX_PATH * sizeof (WCHAR))))
     api_fatal ("Internal error: Out of memory for new wide path buf.");
   return tls_pbuf.w_buf[tls_pbuf.w_cnt++];
 }
index b4a2a7a..d4143aa 100644 (file)
@@ -17,4 +17,11 @@ public:
   char *c_get ();  /* Create temporary TLS path buf of size NT_MAX_PATH. */
   PWCHAR w_get (); /* Create temporary TLS path buf of size 2 * NT_MAX_PATH. */
   inline char *t_get () { return (char *) w_get (); }
+  inline PUNICODE_STRING u_get (PUNICODE_STRING up)
+    {
+      up->Length = 0;
+      up->MaximumLength = (NT_MAX_PATH - 1) * sizeof (WCHAR);
+      up->Buffer = w_get ();
+      return up;
+    }
 };
index ae7e85c..6f1dd97 100644 (file)
@@ -30,6 +30,7 @@ details. */
 #include "child_info.h"
 #include "environ.h"
 #include "pwdgrp.h"
+#include "tls_pbuf.h"
 #include "ntdll.h"
 
 /* Initialize the part of cygheap_user that does not depend on files.
@@ -240,11 +241,10 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
   LPUSER_INFO_3 ui = NULL;
   WCHAR wuser[UNLEN + 1];
   NET_API_STATUS ret;
-  char homepath_env_buf[CYG_MAX_PATH];
   char homedrive_env_buf[3];
   char *newhomedrive = NULL;
   char *newhomepath = NULL;
-
+  tmp_pathbuf tp;
 
   debug_printf ("what %d, pw %p", what, pw);
   if (what == CH_HOME)
@@ -273,11 +273,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
            setenv ("HOME", "/", 1);
          else
            {
-             char home[CYG_MAX_PATH];
-             char buf[CYG_MAX_PATH];
+             char *home = tp.c_get ();
+             char *buf = tp.c_get ();
              strcpy (buf, newhomedrive);
              strcat (buf, newhomepath);
-             cygwin_conv_to_full_posix_path (buf, home);
+             cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, buf, home,
+                               NT_MAX_PATH);
              debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home);
              setenv ("HOME", home, 1);
            }
@@ -286,10 +287,12 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
 
   if (what != CH_HOME && homepath == NULL && newhomepath == NULL)
     {
+      char *homepath_env_buf = tp.c_get ();
       if (!pw)
        pw = internal_getpwnam (name ());
       if (pw && pw->pw_dir && *pw->pw_dir)
-       cygwin_conv_to_full_win32_path (pw->pw_dir, homepath_env_buf);
+       cygwin_conv_path (CCP_POSIX_TO_WIN_A, pw->pw_dir, homepath_env_buf,
+                         NT_MAX_PATH);
       else
        {
          homepath_env_buf[0] = homepath_env_buf[1] = '\0';
@@ -301,16 +304,17 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
             sys_mbstowcs (wuser, sizeof (wuser) / sizeof (*wuser), winname ());
              if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
                {
-                 sys_wcstombs (homepath_env_buf, CYG_MAX_PATH,
+                 sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
                                ui->usri3_home_dir);
                  if (!homepath_env_buf[0])
                    {
-                     sys_wcstombs (homepath_env_buf, CYG_MAX_PATH,
+                     sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
                                    ui->usri3_home_dir_drive);
                      if (homepath_env_buf[0])
                        strcat (homepath_env_buf, "\\");
                      else
-                       cygwin_conv_to_full_win32_path ("/", homepath_env_buf);
+                       cygwin_conv_path (CCP_POSIX_TO_WIN_A | CCP_ABSOLUTE,
+                                         "/", homepath_env_buf, NT_MAX_PATH);
                    }
                }
            }
index 033de7b..4be4002 100644 (file)
@@ -141,7 +141,8 @@ av::unshift (const char *what, int conv)
   char *buf = tp.c_get ();
   if (conv)
     {
-      cygwin_conv_to_posix_path (what, buf);
+      cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_RELATIVE, what, buf,
+                       NT_MAX_PATH);
       char *p = strchr (buf, '\0') - 4;
       if (p > buf && ascii_strcasematch (p, ".exe"))
        *p = '\0';
index e10ffe9..55db729 100644 (file)
@@ -81,13 +81,8 @@ extern unsigned long cygwin_inet_addr (const char *cp);
    buffer sizes.  As MAX_PATH and PATH_MAX, this is defined including the
    trailing 0.  Internal buffers and internal path routines should use
    NT_MAX_PATH.  PATH_MAX as defined in limits.h is the maximum length of
-   application provided path strings we handle.
-   
-   Note that it's defined one less than 32K.  This is not only big enough,
-   it also allows to use the value in UNICODE_STRING fields Length and
-   MaximumLength when multiplied with sizeof (WCHAR).  Both fields are
-   USHORT... */
-#define NT_MAX_PATH 32767
+   application provided path strings we handle. */
+#define NT_MAX_PATH 32768
 
 #ifdef __cplusplus