Commit 516b4ebd authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msvcrt: Rewrite _spawnve as a wrapper.

parent c91a5973
...@@ -35,54 +35,7 @@ ...@@ -35,54 +35,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* INTERNAL: Spawn a child process */ static MSVCRT_intptr_t msvcrt_spawn(int flags, const MSVCRT_wchar_t* exe, MSVCRT_wchar_t* cmdline, MSVCRT_wchar_t* env)
static MSVCRT_intptr_t msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
if ((unsigned)flags > MSVCRT__P_DETACH)
{
*MSVCRT__errno() = MSVCRT_EINVAL;
return -1;
}
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
msvcrt_create_io_inherit_block(&si.cbReserved2, &si.lpReserved2);
if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
flags == MSVCRT__P_DETACH ? DETACHED_PROCESS : 0,
env, NULL, &si, &pi))
{
msvcrt_set_errno(GetLastError());
MSVCRT_free(si.lpReserved2);
return -1;
}
MSVCRT_free(si.lpReserved2);
switch(flags)
{
case MSVCRT__P_WAIT:
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess,&pi.dwProcessId);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return pi.dwProcessId;
case MSVCRT__P_DETACH:
CloseHandle(pi.hProcess);
pi.hProcess = 0;
/* fall through */
case MSVCRT__P_NOWAIT:
case MSVCRT__P_NOWAITO:
CloseHandle(pi.hThread);
return (MSVCRT_intptr_t)pi.hProcess;
case MSVCRT__P_OVERLAY:
MSVCRT__exit(0);
}
return -1; /* can't reach here */
}
static MSVCRT_intptr_t msvcrt_spawn_wide(int flags, const MSVCRT_wchar_t* exe, MSVCRT_wchar_t* cmdline, MSVCRT_wchar_t* env)
{ {
STARTUPINFOW si; STARTUPINFOW si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
...@@ -128,52 +81,7 @@ static MSVCRT_intptr_t msvcrt_spawn_wide(int flags, const MSVCRT_wchar_t* exe, M ...@@ -128,52 +81,7 @@ static MSVCRT_intptr_t msvcrt_spawn_wide(int flags, const MSVCRT_wchar_t* exe, M
return -1; /* can't reach here */ return -1; /* can't reach here */
} }
/* INTERNAL: Convert argv list to a single 'delim'-separated string, with an static MSVCRT_wchar_t* msvcrt_argvtos(const MSVCRT_wchar_t* const* arg, MSVCRT_wchar_t delim)
* extra '\0' to terminate it
*/
static char* msvcrt_argvtos(const char* const* arg, char delim)
{
const char* const* a;
long size;
char* p;
char* ret;
if (!arg && !delim)
{
/* Return NULL for an empty environment list */
return NULL;
}
/* get length */
a = arg;
size = 0;
while (*a)
{
size += strlen(*a) + 1;
a++;
}
ret = MSVCRT_malloc(size + 1);
if (!ret)
return NULL;
/* fill string */
a = arg;
p = ret;
while (*a)
{
int len = strlen(*a);
memcpy(p,*a,len);
p += len;
*p++ = delim;
a++;
}
if (delim && p > ret) p[-1] = 0;
else *p = 0;
return ret;
}
static MSVCRT_wchar_t* msvcrt_argvtos_wide(const MSVCRT_wchar_t* const* arg, MSVCRT_wchar_t delim)
{ {
const MSVCRT_wchar_t* const* a; const MSVCRT_wchar_t* const* a;
long size; long size;
...@@ -375,7 +283,7 @@ MSVCRT_intptr_t CDECL _execl(const char* name, const char* arg0, ...) ...@@ -375,7 +283,7 @@ MSVCRT_intptr_t CDECL _execl(const char* name, const char* arg0, ...)
args = msvcrt_valisttos_aw(arg0, ap, ' '); args = msvcrt_valisttos_aw(arg0, ap, ' ');
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, nameW, args, NULL); ret = msvcrt_spawn(MSVCRT__P_OVERLAY, nameW, args, NULL);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -404,7 +312,7 @@ MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...) ...@@ -404,7 +312,7 @@ MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...)
if (envp) envs = msvcrt_argvtos_aw(envp, 0); if (envp) envs = msvcrt_argvtos_aw(envp, 0);
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, nameW, args, envs); ret = msvcrt_spawn(MSVCRT__P_OVERLAY, nameW, args, envs);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -432,7 +340,7 @@ MSVCRT_intptr_t CDECL _execlp(const char* name, const char* arg0, ...) ...@@ -432,7 +340,7 @@ MSVCRT_intptr_t CDECL _execlp(const char* name, const char* arg0, ...)
args = msvcrt_valisttos_aw(arg0, ap, ' '); args = msvcrt_valisttos_aw(arg0, ap, ' ');
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, fullname[0] ? fullname : nameW, args, NULL); ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : nameW, args, NULL);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -463,7 +371,7 @@ MSVCRT_intptr_t CDECL _execlpe(const char* name, const char* arg0, ...) ...@@ -463,7 +371,7 @@ MSVCRT_intptr_t CDECL _execlpe(const char* name, const char* arg0, ...)
if (envp) envs = msvcrt_argvtos_aw(envp, 0); if (envp) envs = msvcrt_argvtos_aw(envp, 0);
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(MSVCRT__P_OVERLAY, fullname[0] ? fullname : nameW, args, envs); ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : nameW, args, envs);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -537,7 +445,7 @@ MSVCRT_intptr_t CDECL _spawnl(int flags, const char* name, const char* arg0, ... ...@@ -537,7 +445,7 @@ MSVCRT_intptr_t CDECL _spawnl(int flags, const char* name, const char* arg0, ...
args = msvcrt_valisttos_aw(arg0, ap, ' '); args = msvcrt_valisttos_aw(arg0, ap, ' ');
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(flags, nameW, args, NULL); ret = msvcrt_spawn(flags, nameW, args, NULL);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -566,7 +474,7 @@ MSVCRT_intptr_t CDECL _spawnle(int flags, const char* name, const char* arg0, .. ...@@ -566,7 +474,7 @@ MSVCRT_intptr_t CDECL _spawnle(int flags, const char* name, const char* arg0, ..
if (envp) envs = msvcrt_argvtos_aw(envp, 0); if (envp) envs = msvcrt_argvtos_aw(envp, 0);
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(flags, nameW, args, envs); ret = msvcrt_spawn(flags, nameW, args, envs);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -595,7 +503,7 @@ MSVCRT_intptr_t CDECL _spawnlp(int flags, const char* name, const char* arg0, .. ...@@ -595,7 +503,7 @@ MSVCRT_intptr_t CDECL _spawnlp(int flags, const char* name, const char* arg0, ..
args = msvcrt_valisttos_aw(arg0, ap, ' '); args = msvcrt_valisttos_aw(arg0, ap, ' ');
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(flags, fullname[0] ? fullname : nameW, args, NULL); ret = msvcrt_spawn(flags, fullname[0] ? fullname : nameW, args, NULL);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -626,7 +534,7 @@ MSVCRT_intptr_t CDECL _spawnlpe(int flags, const char* name, const char* arg0, . ...@@ -626,7 +534,7 @@ MSVCRT_intptr_t CDECL _spawnlpe(int flags, const char* name, const char* arg0, .
if (envp) envs = msvcrt_argvtos_aw(envp, 0); if (envp) envs = msvcrt_argvtos_aw(envp, 0);
va_end(ap); va_end(ap);
ret = msvcrt_spawn_wide(flags, fullname[0] ? fullname : nameW, args, envs); ret = msvcrt_spawn(flags, fullname[0] ? fullname : nameW, args, envs);
MSVCRT_free(nameW); MSVCRT_free(nameW);
MSVCRT_free(args); MSVCRT_free(args);
...@@ -643,50 +551,19 @@ MSVCRT_intptr_t CDECL _spawnlpe(int flags, const char* name, const char* arg0, . ...@@ -643,50 +551,19 @@ MSVCRT_intptr_t CDECL _spawnlpe(int flags, const char* name, const char* arg0, .
MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* argv, MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* argv,
const char* const* envv) const char* const* envv)
{ {
char * args = msvcrt_argvtos(argv,' '); MSVCRT_wchar_t *nameW, *args, *envs;
char * envs = msvcrt_argvtos(envv,0); MSVCRT_intptr_t ret;
char fullname[MAX_PATH];
const char *p;
int len;
MSVCRT_intptr_t ret = -1;
TRACE(":call (%s), params (%s), env (%s)\n",debugstr_a(name),debugstr_a(args),
envs?"Custom":"Null");
/* no check for NULL name.
native doesn't do it */
p = memchr(name, '\0', MAX_PATH);
if( !p )
p = name + MAX_PATH - 1;
len = p - name;
/* extra-long names are silently truncated. */
memcpy(fullname, name, len);
for( p--; p >= name; p-- ) if (!(nameW = msvcrt_wstrdupa(name))) return -1;
{
if( *p == '\\' || *p == '/' || *p == ':' || *p == '.' )
break;
}
/* if no extension is given, assume .exe */ args = msvcrt_argvtos_aw(argv, ' ');
if( (p < name || *p != '.') && len <= MAX_PATH - 5 ) envs = msvcrt_argvtos_aw(envv, 0);
{
FIXME("only trying .exe when no extension given\n");
memcpy(fullname+len, ".exe", 4);
len += 4;
}
fullname[len] = '\0'; ret = msvcrt_spawn(flags, nameW, args, envs);
if (args) MSVCRT_free(nameW);
{ MSVCRT_free(args);
ret = msvcrt_spawn(flags, fullname, args, envs);
MSVCRT_free(args);
}
MSVCRT_free(envs); MSVCRT_free(envs);
return ret; return ret;
} }
...@@ -698,8 +575,8 @@ MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* a ...@@ -698,8 +575,8 @@ MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* a
MSVCRT_intptr_t CDECL _wspawnve(int flags, const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* const* argv, MSVCRT_intptr_t CDECL _wspawnve(int flags, const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* const* argv,
const MSVCRT_wchar_t* const* envv) const MSVCRT_wchar_t* const* envv)
{ {
MSVCRT_wchar_t * args = msvcrt_argvtos_wide(argv,' '); MSVCRT_wchar_t * args = msvcrt_argvtos(argv,' ');
MSVCRT_wchar_t * envs = msvcrt_argvtos_wide(envv,0); MSVCRT_wchar_t * envs = msvcrt_argvtos(envv,0);
MSVCRT_wchar_t fullname[MAX_PATH]; MSVCRT_wchar_t fullname[MAX_PATH];
const MSVCRT_wchar_t *p; const MSVCRT_wchar_t *p;
int len; int len;
...@@ -739,7 +616,7 @@ MSVCRT_intptr_t CDECL _wspawnve(int flags, const MSVCRT_wchar_t* name, const MSV ...@@ -739,7 +616,7 @@ MSVCRT_intptr_t CDECL _wspawnve(int flags, const MSVCRT_wchar_t* name, const MSV
if (args) if (args)
{ {
ret = msvcrt_spawn_wide(flags, fullname, args, envs); ret = msvcrt_spawn(flags, fullname, args, envs);
MSVCRT_free(args); MSVCRT_free(args);
} }
MSVCRT_free(envs); MSVCRT_free(envs);
...@@ -888,7 +765,7 @@ MSVCRT_FILE* CDECL MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wc ...@@ -888,7 +765,7 @@ MSVCRT_FILE* CDECL MSVCRT__wpopen(const MSVCRT_wchar_t* command, const MSVCRT_wc
strcatW(fullcmd, command); strcatW(fullcmd, command);
HeapFree(GetProcessHeap(), 0, comspec); HeapFree(GetProcessHeap(), 0, comspec);
if (msvcrt_spawn_wide(MSVCRT__P_NOWAIT, NULL, fullcmd, NULL) == -1) if (msvcrt_spawn(MSVCRT__P_NOWAIT, NULL, fullcmd, NULL) == -1)
{ {
MSVCRT__close(fds[fdToOpen]); MSVCRT__close(fds[fdToOpen]);
ret = NULL; ret = NULL;
...@@ -976,7 +853,7 @@ int CDECL _wsystem(const MSVCRT_wchar_t* cmd) ...@@ -976,7 +853,7 @@ int CDECL _wsystem(const MSVCRT_wchar_t* cmd)
strcatW(fullcmd, flag); strcatW(fullcmd, flag);
strcatW(fullcmd, cmd); strcatW(fullcmd, cmd);
res = msvcrt_spawn_wide(MSVCRT__P_WAIT, comspec, fullcmd, NULL); res = msvcrt_spawn(MSVCRT__P_WAIT, comspec, fullcmd, NULL);
HeapFree(GetProcessHeap(), 0, comspec); HeapFree(GetProcessHeap(), 0, comspec);
HeapFree(GetProcessHeap(), 0, fullcmd); HeapFree(GetProcessHeap(), 0, fullcmd);
......
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