msvcrt-B07: _wsystem

Jaco Greeff jaco at puxedo.org
Tue Nov 5 06:35:08 CST 2002


License:
LGPL

Changelog:
* dlls/msvcrt/msvcrt.spec, dlls/msvcrt/process.c: Jaco Greeff 
<jaco at puxedo.org>
- Implemented the Unicode version of system, the _wsystem call
-------------- next part --------------
diff -aurN msvcrt-B06/dlls/msvcrt/msvcrt.spec msvcrt-B07/dlls/msvcrt/msvcrt.spec
--- msvcrt-B06/dlls/msvcrt/msvcrt.spec	Tue Nov  5 12:30:09 2002
+++ msvcrt-B07/dlls/msvcrt/msvcrt.spec	Tue Nov  5 14:05:40 2002
@@ -556,7 +556,7 @@
 @ stub _wstati64 #(wstr ptr)
 @ stub _wstrdate #(wstr)
 @ stub _wstrtime #(wstr)
-@ stub _wsystem #(wstr)
+@ cdecl _wsystem(wstr)
 @ cdecl _wtempnam(wstr wstr) _wtempnam
 @ stub _wtmpnam #(wstr)
 @ forward -noimport _wtoi NTDLL._wtoi
diff -aurN msvcrt-B06/dlls/msvcrt/process.c msvcrt-B07/dlls/msvcrt/process.c
--- msvcrt-B06/dlls/msvcrt/process.c	Tue Nov  5 13:04:49 2002
+++ msvcrt-B07/dlls/msvcrt/process.c	Tue Nov  5 14:33:22 2002
@@ -38,10 +38,18 @@
 #include "msvcrt/stdlib.h"
 #include "msvcrt/string.h"
 
+#include "wine/unicode.h"
+
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 
+/* ASCII and Unicode representations of the COMSPEC variable
+ * name. This is used to extract it from the environment
+ */
+static const char szCOMSPEC[] = "COMSPEC";
+static const WCHAR wszCOMSPEC[] = {'C','O','M','S','P','E','C', 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';
@@ -98,6 +106,63 @@
   return -1; /* can't reach here */
 }
 
+/* INTERNAL: Spawn a child process using WCHAR arguments
+ * (This is a direct "port" of the msvcrt_spawn function
+ * to support Unicode strings)
+ */
+static int msvcrt_spawnW(int flags, const WCHAR* wszExe, WCHAR *wszCmdline, WCHAR *wszEnv)
+{
+    STARTUPINFOW si;
+    PROCESS_INFORMATION pi;
+
+    /* FIXME: this is not a problem at present, but might become
+     * so in the future when we move to 64 bit and support Win64
+     * (The same comment applies to msvcrt_spawn)
+     */
+    if (sizeof(HANDLE) != sizeof(int))
+        WARN("This call is unsuitable for your architecture\n");
+
+    if ((unsigned)flags > _P_DETACH)
+    {
+        *MSVCRT__errno() = MSVCRT_EINVAL;
+        return -1;
+    }
+
+    FIXME(":must dup/kill streams for child process\n");
+
+    memset(&si, 0, sizeof(si));
+    si.cb = sizeof(si);
+
+    if (!CreateProcessW(wszExe, wszCmdline, NULL, NULL, TRUE,
+                        flags == _P_DETACH ? DETACHED_PROCESS : 0,
+                        wszEnv, NULL, &si, &pi))
+    {
+        MSVCRT__set_errno(GetLastError());
+        return -1;
+    }
+
+    switch(flags)
+    {
+    case _P_WAIT:
+        WaitForSingleObject(pi.hProcess,-1); /* wait forvever */
+        GetExitCodeProcess(pi.hProcess,&pi.dwProcessId);
+        CloseHandle(pi.hProcess);
+        CloseHandle(pi.hThread);
+        return (int)pi.dwProcessId;
+    case _P_DETACH:
+        CloseHandle(pi.hProcess);
+        pi.hProcess = 0;
+        /* fall through */
+    case _P_NOWAIT:
+    case _P_NOWAITO:
+        CloseHandle(pi.hThread);
+        return (int)pi.hProcess;
+    case  _P_OVERLAY:
+        MSVCRT__exit(0);
+    }
+    return -1; /* can't reach here */
+}
+
 /* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
  * extra '\0' to terminate it
  */
@@ -450,9 +515,9 @@
      * default command interpreter. If the interpreter is
      * not available, fail.
      */
-    if (!GetEnvironmentVariableA("COMSPEC", szComspec, 1024))
+    if (!GetEnvironmentVariableA(szCOMSPEC, szComspec, 1024))
     {
-        TRACE("COMSPEC not available, _system call fails\n");
+        TRACE("COMSPEC not available, system call fails\n");
         return -1;
     }
 
@@ -462,13 +527,53 @@
      */
     if (!(cmdcopy = (char *)MSVCRT_malloc(strlen(szComspec)+strlen(szExec)+strlen(cmd)+1)))
     {
-        TRACE("Unable to allocate memory for _system call\n");
+        TRACE("Unable to allocate memory for system call\n");
         return -1;
     }
     sprintf(cmdcopy, "%s%s%s", szComspec, szExec, cmd);
 
     res=msvcrt_spawn(_P_WAIT, NULL, cmdcopy, NULL);
     MSVCRT_free(cmdcopy);
+    return res;
+}
+
+/*********************************************************************
+ *		_wsystem (MSVCRT.@)
+ */
+int MSVCRT__wsystem(const WCHAR* wszCmd)
+{
+    static const WCHAR wszExec[] = {' ','/','c',' ', 0};
+    WCHAR wszComspec[1024+1];
+    WCHAR* wszCmdcopy;
+    int res, nLen;
+
+    /* Get the value of COMSPEC which should point to our
+     * default command interpreter. If the interpreter is
+     * not available, fail.
+     */
+    if (!GetEnvironmentVariableW(wszCOMSPEC, wszComspec, 1024))
+    {
+        TRACE("COMSPEC not available, _wsystem call fails\n");
+        return -1;
+    }
+
+    /* Allocate enough memory to hold the interpreter + command
+     * string and set it. When using the command interpreter in
+     * this way, it is executed as "comspec /c command"
+     */
+    nLen = strlenW(wszComspec)+strlenW(wszExec)+strlenW(wszCmd);
+    if (!(wszCmdcopy = (WCHAR *)MSVCRT_malloc(nLen+1)))
+    {
+        TRACE("Unable to allocate memory for _wsystem call\n");
+        return -1;
+    }
+    wszCmdcopy[0] = 0;
+    strcatW(wszCmdcopy, wszComspec);
+    strcatW(wszCmdcopy, wszExec);
+    strcatW(wszCmdcopy, wszCmd);
+
+    res=msvcrt_spawnW(_P_WAIT, NULL, wszCmdcopy, NULL);
+    MSVCRT_free(wszCmdcopy);
     return res;
 }
 


More information about the wine-patches mailing list