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

oldstable
Hans Leidekker 2008-01-07 14:22:23 +01:00 committed by Alexandre Julliard
parent 2adba0d7cd
commit 3debf28215
4 changed files with 60 additions and 11 deletions

View File

@ -229,7 +229,7 @@ char*** CDECL __p___initenv(void) { return &MSVCRT___initenv; }
MSVCRT_wchar_t*** CDECL __p___winitenv(void) { return &MSVCRT___winitenv; }
/* 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 ;
MSVCRT_wchar_t *wstr = MSVCRT_malloc(len* sizeof (MSVCRT_wchar_t));
@ -249,7 +249,7 @@ void msvcrt_init_args(void)
DWORD version;
MSVCRT__acmdln = _strdup( GetCommandLineA() );
MSVCRT__wcmdln = wstrdupa(MSVCRT__acmdln);
MSVCRT__wcmdln = msvcrt_wstrdupa(MSVCRT__acmdln);
MSVCRT___argc = __wine_main_argc;
MSVCRT___argv = __wine_main_argv;
MSVCRT___wargv = __wine_main_wargv;

View File

@ -125,6 +125,8 @@ extern MSVCRT_wchar_t **_wenviron;
extern char ** msvcrt_SnapshotOfEnvironmentA(char **);
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
* it would not be much use anyway. Even for Winelib applications.
*/

View File

@ -570,7 +570,7 @@
@ cdecl _wstat64(wstr ptr) MSVCRT__wstat64
@ cdecl _wstrdate(ptr)
@ cdecl _wstrtime(ptr)
@ stub _wsystem #(wstr)
@ cdecl _wsystem(wstr)
@ cdecl _wtempnam(wstr wstr)
@ stub _wtmpnam #(ptr)
@ cdecl _wtoi(wstr) ntdll._wtoi

View File

@ -269,6 +269,22 @@ static char* msvcrt_valisttos(const char* arg0, va_list alist, char delim)
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.@)
*/
@ -821,20 +837,51 @@ int CDECL MSVCRT__pclose(MSVCRT_FILE* file)
return MSVCRT_fclose(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.@)
*/
int CDECL MSVCRT_system(const char* cmd)
{
char* cmdcopy;
int res;
int res = -1;
MSVCRT_wchar_t *cmdW;
/* Make a writable copy for CreateProcess */
cmdcopy=_strdup(cmd);
/* FIXME: should probably launch cmd interpreter in COMSPEC */
res=msvcrt_spawn(MSVCRT__P_WAIT, NULL, cmdcopy, NULL);
MSVCRT_free(cmdcopy);
return res;
if ((cmdW = msvcrt_wstrdupa(cmd)))
{
res = _wsystem(cmdW);
HeapFree(GetProcessHeap(), 0, cmdW);
}
return res;
}
/*********************************************************************