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