msvcrt-B09: _wsearchenv/_wexecl/_wexeclp/_wspawnl/_wspanwlp

Jaco Greeff jaco at puxedo.org
Tue Nov 5 09:29:44 CST 2002


Implementation of the above functions, basically just "ports" of their 
ASCII equivalents.

License:
LGPL

Changelog:
* dlls/msvcrt/msvcrt.spec, dlls/msvcrt/dir.c, dlls/msvcrt/process.c: 
Jaco Greeff <jaco at puxedo.org>
- Implementation of _wsearchenv
- Implementation of _wexecl and _wexeclp
- Implementation of _wspawnl and _wspawnlp
-------------- next part --------------
diff -aurN msvcrt-B08/dlls/msvcrt/dir.c msvcrt-B09/dlls/msvcrt/dir.c
--- msvcrt-B08/dlls/msvcrt/dir.c	Fri Oct 25 05:12:01 2002
+++ msvcrt-B09/dlls/msvcrt/dir.c	Tue Nov  5 17:23:24 2002
@@ -5,6 +5,7 @@
  * Copyright 1996 Jukka Iivonen
  * Copyright 1997,2000 Uwe Bonnes
  * Copyright 2000 Jon Griffiths
+ * Copyright 2002 Jaco Greeff
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -812,6 +813,71 @@
     if (GetFileAttributesA( curPath ) != 0xFFFFFFFF)
     {
       strcpy(buf, curPath);
+      MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
+      return; /* Found */
+    }
+    penv = *end ? end + 1 : end;
+  } while(1);
+}
+
+/*********************************************************************
+ *      _wsearchenv (MSVCRT.@)
+ * (This is a straight "port" to Unicode of the _searchenv function)
+ */
+void _wsearchenv(const WCHAR* file, const WCHAR* env, WCHAR *buf)
+{
+  WCHAR *envVal, *penv;
+  WCHAR curPath[MAX_PATH];
+
+  *buf = '\0';
+
+  /* Try CWD first */
+  if (GetFileAttributesW(file) != 0xFFFFFFFF)
+  {
+    GetFullPathNameW(file, MAX_PATH, buf, NULL);
+    /* Sigh. This error is *always* set, regardless of success */
+    MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
+    return;
+  }
+
+  /* Search given environment variable */
+  envVal = _wgetenv(env);
+  if (!envVal)
+  {
+    MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
+    return;
+  }
+
+  penv = envVal;
+  do
+  {
+    WCHAR *end = penv;
+    int len;
+
+    len = 0;
+    while (*end && *end != ';')
+    {
+        end++; /* Find end of next path */
+        len++;
+    }
+    if (penv == end || !*penv)
+    {
+      MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
+      return;
+    }
+    strncpyW(curPath, penv, len);
+    if (curPath[len] != '/' || curPath[len] != '\\')
+    {
+      curPath[len] = '\\';
+      curPath[len + 1] = '\0';
+    }
+    else
+      curPath[len] = '\0';
+
+    strcatW(curPath, file);
+    if (GetFileAttributesW(curPath) != 0xFFFFFFFF)
+    {
+      strcpyW(buf, curPath);
       MSVCRT__set_errno(ERROR_FILE_NOT_FOUND);
       return; /* Found */
     }
diff -aurN msvcrt-B08/dlls/msvcrt/msvcrt.spec msvcrt-B09/dlls/msvcrt/msvcrt.spec
--- msvcrt-B08/dlls/msvcrt/msvcrt.spec	Tue Nov  5 14:05:40 2002
+++ msvcrt-B09/dlls/msvcrt/msvcrt.spec	Tue Nov  5 17:11:33 2002
@@ -505,9 +505,9 @@
 @ forward -noimport _wcsupr ntdll._wcsupr
 @ stub _wctime #(ptr)
 @ extern _wenviron MSVCRT__wenviron
-@ stub _wexecl #(wstr wstr) varargs
+@ varargs _wexecl(wstr wstr) _wexecl
 @ stub _wexecle #(wstr wstr) varargs
-@ stub _wexeclp #(wstr wstr) varargs
+@ varargs _wexeclp(wstr wstr) _wexeclp
 @ stub _wexeclpe #(wstr wstr) varargs
 @ stub _wexecv #(wstr wstr)
 @ stub _wexecve #(wstr wstr wstr)
@@ -540,12 +540,12 @@
 @ cdecl _wrename(wstr wstr) _wrename
 @ cdecl _write(long ptr long) _write
 @ cdecl _wrmdir(wstr) _wrmdir
-@ stub _wsearchenv #(wstr wstr wstr)
+@ cdecl _wsearchenv(wstr wstr wstr) _wsearchenv
 @ stub _wsetlocale #(long wstr)
-@ varargs _wsopen (wstr long long) MSVCRT__wsopen
-@ stub _wspawnl #(long wstr wstr) varargs
+@ varargs _wsopen(wstr long long) MSVCRT__wsopen
+@ varargs _wspawnl(long wstr wstr) _wspawnl
 @ stub _wspawnle #(long wstr wstr) varargs
-@ stub _wspawnlp #(long wstr wstr) varargs
+@ varargs _wspawnlp(long wstr wstr) _wspawnlp
 @ stub _wspawnlpe #(long wstr wstr) varargs
 @ stub _wspawnv #(long wstr wstr)
 @ stub _wspawnve #(long wstr wstr wstr)
@@ -556,7 +556,7 @@
 @ stub _wstati64 #(wstr ptr)
 @ stub _wstrdate #(wstr)
 @ stub _wstrtime #(wstr)
-@ cdecl _wsystem(wstr)
+@ cdecl _wsystem(wstr) MSVCRT__wsystem
 @ cdecl _wtempnam(wstr wstr) _wtempnam
 @ stub _wtmpnam #(wstr)
 @ forward -noimport _wtoi NTDLL._wtoi
diff -aurN msvcrt-B08/dlls/msvcrt/process.c msvcrt-B09/dlls/msvcrt/process.c
--- msvcrt-B08/dlls/msvcrt/process.c	Tue Nov  5 15:32:50 2002
+++ msvcrt-B09/dlls/msvcrt/process.c	Tue Nov  5 17:00:53 2002
@@ -50,6 +50,9 @@
 static const char szCOMSPEC[] = "COMSPEC";
 static const WCHAR wszCOMSPEC[] = {'C','O','M','S','P','E','C', 0};
 
+static const char szENV_PATH[] = "PATH";
+static const WCHAR wszENV_PATH[] = {'P','A','T','H', 0};
+
 /* FIXME: Check file extensions for app to run */
 static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
 static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
@@ -260,6 +263,59 @@
   return ret;
 }
 
+/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
+ * extra '\0' to terminate it (Unicode "port" of the msvcrt_valisttos
+ * function
+ */
+static WCHAR *msvcrt_valisttows(const WCHAR* arg0, va_list alist, WCHAR delim)
+{
+    va_list alist2;
+    long size;
+    const WCHAR *arg;
+    WCHAR *p;
+    WCHAR *ret;
+
+#if HAVE_VA_COPY
+    va_copy(alist2,alist);
+#else
+# if HAVE___VA_COPY
+    __va_copy(alist2,alist);
+# else
+    alist2 = alist;
+# endif
+#endif
+
+    /* Return NULL for an empty environment list */
+    if (!arg0 && !delim)
+        return NULL;
+
+    /* get length */
+    arg = arg0;
+    size = 0;
+    do
+    {
+        size += strlenW(arg)+1; /* +1 for length of delim */
+        arg = va_arg(alist, WCHAR *);
+    } while (arg != NULL);
+
+    ret = (WCHAR *)MSVCRT_malloc((size+1)*sizeof(WCHAR));
+    if (!ret)
+        return NULL;
+
+    /* fill string */
+    arg = arg0;
+    p = ret;
+    do {
+        int len = strlenW(arg);
+        memcpy(p, arg, len*sizeof(WCHAR));
+        p += len;
+        *p++ = delim;
+        arg = va_arg(alist2, WCHAR *);
+    } while (arg != NULL);
+    *p = 0;
+    return ret;
+}
+
 /*********************************************************************
  *		_cwait (MSVCRT.@)
  */
@@ -316,6 +372,28 @@
 }
 
 /*********************************************************************
+ *      _wexecl (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces
+ * or double-quotes. (Unicode version of _execl)
+ */
+int _wexecl(const WCHAR *name, const WCHAR* arg0, ...)
+{
+    va_list ap;
+    WCHAR *args;
+    int ret;
+
+    va_start(ap, arg0);
+    args = msvcrt_valisttows(arg0, ap, ' ');
+    va_end(ap);
+
+    ret = msvcrt_spawnW(_P_OVERLAY, name, args, NULL);
+    MSVCRT_free(args);
+
+    return ret;
+}
+
+/*********************************************************************
  *		_execlp (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -328,7 +406,7 @@
   int ret;
   char fullname[MAX_PATH];
 
-  _searchenv(name, "PATH", fullname);
+  _searchenv(name, szENV_PATH, fullname);
 
   va_start(ap, arg0);
   args = msvcrt_valisttos(arg0, ap, ' ');
@@ -341,6 +419,31 @@
 }
 
 /*********************************************************************
+ *      _wexeclp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces
+ * or double-quotes. (Unicode version of _execlp)
+ */
+int _wexeclp(const WCHAR* name, const WCHAR* arg0, ...)
+{
+    va_list ap;
+    WCHAR *args;
+    int ret;
+    WCHAR fullname[MAX_PATH];
+
+    _wsearchenv(name, wszENV_PATH, fullname);
+
+    va_start(ap, arg0);
+    args = msvcrt_valisttows(arg0, ap, ' ');
+    va_end(ap);
+
+    ret = msvcrt_spawnW(_P_OVERLAY, fullname[0] ? fullname : name, args, NULL);
+    MSVCRT_free(args);
+
+    return ret;
+}
+
+/*********************************************************************
  *		_execv (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -372,7 +475,7 @@
 {
   char fullname[MAX_PATH];
 
-  _searchenv(name, "PATH", fullname);
+  _searchenv(name, szENV_PATH, fullname);
   return _spawnve(_P_OVERLAY, fullname[0] ? fullname : name,
                   (const char* const*) argv, envv);
 }
@@ -411,6 +514,28 @@
 }
 
 /*********************************************************************
+ *      _wspawnl (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces
+ * or double-quotes. (Unicode version of the _spawnl function)
+ */
+int _wspawnl(int flags, const WCHAR *name, const WCHAR* arg0, ...)
+{
+    va_list ap;
+    WCHAR *args;
+    int ret;
+
+    va_start(ap, arg0);
+    args = msvcrt_valisttows(arg0, ap, ' ');
+    va_end(ap);
+
+    ret = msvcrt_spawnW(flags, name, args, NULL);
+    MSVCRT_free(args);
+
+    return ret;
+}
+
+/*********************************************************************
  *		_spawnlp (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -423,7 +548,7 @@
   int ret;
   char fullname[MAX_PATH];
 
-  _searchenv(name, "PATH", fullname);
+  _searchenv(name, szENV_PATH, fullname);
 
   va_start(ap, arg0);
   args = msvcrt_valisttos(arg0, ap, ' ');
@@ -436,6 +561,31 @@
 }
 
 /*********************************************************************
+ *      _wspawnlp (MSVCRT.@)
+ *
+ * Like on Windows, this function does not handle arguments with spaces
+ * or double-quotes. (Unicode version of _spawnlp)
+ */
+int _wspawnlp(int flags, const WCHAR *name, const WCHAR *arg0, ...)
+{
+    va_list ap;
+    WCHAR *args;
+    int ret;
+    WCHAR fullname[MAX_PATH];
+
+    _wsearchenv(name, wszENV_PATH, fullname);
+
+    va_start(ap, arg0);
+    args = msvcrt_valisttows(arg0, ap, ' ');
+    va_end(ap);
+
+    ret = msvcrt_spawnW(flags, fullname[0] ? fullname : name, args, NULL);
+    MSVCRT_free(args);
+
+    return ret;
+}
+
+/*********************************************************************
  *		_spawnve (MSVCRT.@)
  *
  * Like on Windows, this function does not handle arguments with spaces
@@ -484,7 +634,7 @@
                             const char* const* envv)
 {
   char fullname[MAX_PATH];
-  _searchenv(name, "PATH", fullname);
+  _searchenv(name, szENV_PATH, fullname);
   return _spawnve(flags, fullname[0] ? fullname : name, argv, envv);
 }
 


More information about the wine-patches mailing list