From 3fd647c24306e12c226b85f2d830e99aa5f90c8a Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 7 Jan 2008 14:23:19 +0100 Subject: [PATCH] msvcrt: Implement _wexecl{, e, p, pe}. --- dlls/msvcrt/msvcrt.spec | 8 +- dlls/msvcrt/process.c | 162 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 4 deletions(-) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index b0fa5e9668f..cff8ecda249 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -518,10 +518,10 @@ @ cdecl _wcsupr(wstr) ntdll._wcsupr @ cdecl _wctime(ptr) MSVCRT__wctime @ extern _wenviron -@ stub _wexecl #(wstr wstr) varargs -@ stub _wexecle #(wstr wstr) varargs -@ stub _wexeclp #(wstr wstr) varargs -@ stub _wexeclpe #(wstr wstr) varargs +@ varargs _wexecl(wstr wstr) +@ varargs _wexecle(wstr wstr) +@ varargs _wexeclp(wstr wstr) +@ varargs _wexeclpe(wstr wstr) @ stub _wexecv #(wstr ptr) @ stub _wexecve #(wstr ptr ptr) @ stub _wexecvp #(wstr ptr) diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c index 7835d88035b..fa8f52a080a 100644 --- a/dlls/msvcrt/process.c +++ b/dlls/msvcrt/process.c @@ -81,6 +81,9 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const MSVCRT_wchar_t* exe, MSVCRT return -1; /* can't reach here */ } +/* INTERNAL: Convert wide argv list to a single 'delim'-separated wide string, with an + * extra '\0' to terminate it. + */ static MSVCRT_wchar_t* msvcrt_argvtos(const MSVCRT_wchar_t* const* arg, MSVCRT_wchar_t delim) { const MSVCRT_wchar_t* const* a; @@ -165,6 +168,59 @@ static MSVCRT_wchar_t *msvcrt_argvtos_aw(const char * const *arg, MSVCRT_wchar_t return ret; } +/* INTERNAL: Convert wide va_list to a single 'delim'-separated wide string, with an + * extra '\0' to terminate it. + */ +static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alist, MSVCRT_wchar_t delim) +{ + va_list alist2; + unsigned long len; + const MSVCRT_wchar_t *arg; + MSVCRT_wchar_t *p, *ret; + +#ifdef HAVE_VA_COPY + va_copy(alist2,alist); +#else +# ifdef HAVE___VA_COPY + __va_copy(alist2,alist); +# else + alist2 = alist; +# endif +#endif + + if (!arg0) + { + /* Return NULL for an empty environment list */ + return NULL; + } + + /* get length */ + arg = arg0; + len = 0; + do { + len += strlenW(arg) + 1; + arg = va_arg(alist, MSVCRT_wchar_t*); + } while (arg != NULL); + + ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t)); + if (!ret) + return NULL; + + /* fill string */ + arg = arg0; + p = ret; + do { + len = strlenW(arg); + memcpy(p, arg, len * sizeof(MSVCRT_wchar_t)); + p += len; + *p++ = delim; + arg = va_arg(alist2, MSVCRT_wchar_t*); + } while (arg != NULL); + if (delim && p > ret) p[-1] = 0; + else *p = 0; + return ret; +} + /* INTERNAL: Convert ansi va_list to a single 'delim'-separated wide string, with an * extra '\0' to terminate it. */ @@ -265,6 +321,27 @@ MSVCRT_intptr_t CDECL _cwait(int *status, MSVCRT_intptr_t pid, int action) return status ? *status = -1 : -1; } +/********************************************************************* + * _wexecl (MSVCRT.@) + * + * Unicode version of _execl + */ +MSVCRT_intptr_t CDECL _wexecl(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...) +{ + va_list ap; + MSVCRT_wchar_t *args; + MSVCRT_intptr_t ret; + + va_start(ap, arg0); + args = msvcrt_valisttos(arg0, ap, ' '); + va_end(ap); + + ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, NULL); + + MSVCRT_free(args); + return ret; +} + /********************************************************************* * _execl (MSVCRT.@) * @@ -290,6 +367,35 @@ MSVCRT_intptr_t CDECL _execl(const char* name, const char* arg0, ...) return ret; } +/********************************************************************* + * _wexecle (MSVCRT.@) + * + * Unicode version of _execle + */ +MSVCRT_intptr_t CDECL _wexecle(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...) +{ + va_list ap; + MSVCRT_wchar_t *args, *envs = NULL; + const MSVCRT_wchar_t * const *envp; + MSVCRT_intptr_t ret; + + va_start(ap, arg0); + args = msvcrt_valisttos(arg0, ap, ' '); + va_end(ap); + + va_start(ap, arg0); + while (va_arg( ap, MSVCRT_wchar_t * ) != NULL) /*nothing*/; + envp = va_arg( ap, const MSVCRT_wchar_t * const * ); + if (envp) envs = msvcrt_argvtos(envp, 0); + va_end(ap); + + ret = msvcrt_spawn(MSVCRT__P_OVERLAY, name, args, envs); + + MSVCRT_free(args); + MSVCRT_free(envs); + return ret; +} + /********************************************************************* * _execle (MSVCRT.@) */ @@ -320,6 +426,30 @@ MSVCRT_intptr_t CDECL _execle(const char* name, const char* arg0, ...) return ret; } +/********************************************************************* + * _wexeclp (MSVCRT.@) + * + * Unicode version of _execlp + */ +MSVCRT_intptr_t CDECL _wexeclp(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...) +{ + static const MSVCRT_wchar_t path[] = {'P','A','T','H',0}; + va_list ap; + MSVCRT_wchar_t *args, fullname[MAX_PATH]; + MSVCRT_intptr_t ret; + + _wsearchenv(name, path, fullname); + + va_start(ap, arg0); + args = msvcrt_valisttos(arg0, ap, ' '); + va_end(ap); + + ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, NULL); + + MSVCRT_free(args); + return ret; +} + /********************************************************************* * _execlp (MSVCRT.@) * @@ -347,6 +477,38 @@ MSVCRT_intptr_t CDECL _execlp(const char* name, const char* arg0, ...) return ret; } +/********************************************************************* + * _wexeclpe (MSVCRT.@) + * + * Unicode version of _execlpe + */ +MSVCRT_intptr_t CDECL _wexeclpe(const MSVCRT_wchar_t* name, const MSVCRT_wchar_t* arg0, ...) +{ + static const MSVCRT_wchar_t path[] = {'P','A','T','H',0}; + va_list ap; + MSVCRT_wchar_t *args, *envs = NULL, fullname[MAX_PATH]; + const MSVCRT_wchar_t * const *envp; + MSVCRT_intptr_t ret; + + _wsearchenv(name, path, fullname); + + va_start(ap, arg0); + args = msvcrt_valisttos(arg0, ap, ' '); + va_end(ap); + + va_start(ap, arg0); + while (va_arg( ap, MSVCRT_wchar_t * ) != NULL) /*nothing*/; + envp = va_arg( ap, const MSVCRT_wchar_t * const * ); + if (envp) envs = msvcrt_argvtos(envp, 0); + va_end(ap); + + ret = msvcrt_spawn(MSVCRT__P_OVERLAY, fullname[0] ? fullname : name, args, envs); + + MSVCRT_free(args); + MSVCRT_free(envs); + return ret; +} + /********************************************************************* * _execlpe (MSVCRT.@) */