Commit 3debf282 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msvcrt: Implement _wsystem and forward system to it. Respect COMSPEC environment variable.

parent 2adba0d7
...@@ -229,7 +229,7 @@ char*** CDECL __p___initenv(void) { return &MSVCRT___initenv; } ...@@ -229,7 +229,7 @@ char*** CDECL __p___initenv(void) { return &MSVCRT___initenv; }
MSVCRT_wchar_t*** CDECL __p___winitenv(void) { return &MSVCRT___winitenv; } MSVCRT_wchar_t*** CDECL __p___winitenv(void) { return &MSVCRT___winitenv; }
/* INTERNAL: Create a wide string from an ascii string */ /* INTERNAL: Create a wide string from an ascii string */
static MSVCRT_wchar_t *wstrdupa(const char *str) MSVCRT_wchar_t *msvcrt_wstrdupa(const char *str)
{ {
const size_t len = strlen(str) + 1 ; const size_t len = strlen(str) + 1 ;
MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t)); MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t));
...@@ -249,7 +249,7 @@ void msvcrt_init_args(void) ...@@ -249,7 +249,7 @@ void msvcrt_init_args(void)
DWORD version; DWORD version;
MSVCRT__acmdln = _strdup( GetCommandLineA() ); MSVCRT__acmdln = _strdup( GetCommandLineA() );
MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln); MSVCRT__wcmdln = msvcrt_wstrdupa(MSVCRT__acmdln);
MSVCRT___argc = __wine_main_argc; MSVCRT___argc = __wine_main_argc;
MSVCRT___argv = __wine_main_argv; MSVCRT___argv = __wine_main_argv;
MSVCRT___wargv = __wine_main_wargv; MSVCRT___wargv = __wine_main_wargv;
......
...@@ -125,6 +125,8 @@ extern MSVCRT_wchar_t **_wenviron; ...@@ -125,6 +125,8 @@ extern MSVCRT_wchar_t **_wenviron;
extern char ** msvcrt_SnapshotOfEnvironmentA(char **); extern char ** msvcrt_SnapshotOfEnvironmentA(char **);
extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **); extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **);
MSVCRT_wchar_t *msvcrt_wstrdupa(const char *);
/* FIXME: This should be declared in new.h but it's not an extern "C" so /* FIXME: This should be declared in new.h but it's not an extern "C" so
* it would not be much use anyway. Even for Winelib applications. * it would not be much use anyway. Even for Winelib applications.
*/ */
......
...@@ -570,7 +570,7 @@ ...@@ -570,7 +570,7 @@
@ cdecl _wstat64(wstr ptr) MSVCRT__wstat64 @ cdecl _wstat64(wstr ptr) MSVCRT__wstat64
@ cdecl _wstrdate(ptr) @ cdecl _wstrdate(ptr)
@ cdecl _wstrtime(ptr) @ cdecl _wstrtime(ptr)
@ stub _wsystem #(wstr) @ cdecl _wsystem(wstr)
@ cdecl _wtempnam(wstr wstr) @ cdecl _wtempnam(wstr wstr)
@ stub _wtmpnam #(ptr) @ stub _wtmpnam #(ptr)
@ cdecl _wtoi(wstr) ntdll._wtoi @ cdecl _wtoi(wstr) ntdll._wtoi
......
...@@ -269,6 +269,22 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim) ...@@ -269,6 +269,22 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
return ret; return ret;
} }
/* INTERNAL: retrieve COMSPEC environment variable */
static MSVCRT_wchar_t *msvcrt_get_comspec(void)
{
static const MSVCRT_wchar_t cmd[] = {'c','m','d',0};
static const MSVCRT_wchar_t comspec[] = {'C','O','M','S','P','E','C',0};
MSVCRT_wchar_t *ret;
unsigned int len;
if (!(len = GetEnvironmentVariableW(comspec, NULL, 0))) len = sizeof(cmd)/sizeof(MSVCRT_wchar_t);
if ((ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t))))
{
if (!GetEnvironmentVariableW(comspec, ret, len)) strcpyW(ret, cmd);
}
return ret;
}
/********************************************************************* /*********************************************************************
* _cwait (MSVCRT.@) * _cwait (MSVCRT.@)
*/ */
...@@ -822,19 +838,50 @@ int CDECL MSVCRT__pclose(MSVCRT_FILE* file) ...@@ -822,19 +838,50 @@ int CDECL MSVCRT__pclose(MSVCRT_FILE* file)
} }
/********************************************************************* /*********************************************************************
* _wsystem (MSVCRT.@)
*
* Unicode version of system
*/
int CDECL _wsystem(const MSVCRT_wchar_t* cmd)
{
int res;
MSVCRT_wchar_t *comspec, *fullcmd;
unsigned int len;
static const MSVCRT_wchar_t flag[] = {' ','/','c',' ',0};
if (!(comspec = msvcrt_get_comspec())) return -1;
len = strlenW(comspec) + strlenW(flag) + strlenW(cmd) + 1;
if (!(fullcmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(MSVCRT_wchar_t))))
{
HeapFree(GetProcessHeap(), 0, comspec);
return -1;
}
strcpyW(fullcmd, comspec);
strcatW(fullcmd, flag);
strcatW(fullcmd, cmd);
res = msvcrt_spawn_wide(MSVCRT__P_WAIT, comspec, fullcmd, NULL);
HeapFree(GetProcessHeap(), 0, comspec);
HeapFree(GetProcessHeap(), 0, fullcmd);
return res;
}
/*********************************************************************
* system (MSVCRT.@) * system (MSVCRT.@)
*/ */
int CDECL MSVCRT_system(const char* cmd) int CDECL MSVCRT_system(const char* cmd)
{ {
char* cmdcopy; int res = -1;
int res; MSVCRT_wchar_t *cmdW;
/* Make a writable copy for CreateProcess */ if ((cmdW = msvcrt_wstrdupa(cmd)))
cmdcopy=_strdup(cmd); {
/* FIXME: should probably launch cmd interpreter in COMSPEC */ res = _wsystem(cmdW);
res=msvcrt_spawn(MSVCRT__P_WAIT, NULL, cmdcopy, NULL); HeapFree(GetProcessHeap(), 0, cmdW);
MSVCRT_free(cmdcopy); }
return res; return res;
} }
/********************************************************************* /*********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment