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