homework-jianmu/2.0/deps/MsvcLibX/src/spawn.c

119 lines
4.6 KiB
C

/*****************************************************************************\
* *
* Filename spawn.c *
* *
* Description: WIN32 UTF-8 version of spawn *
* *
* Notes: *
* *
* History: *
* 2014-03-27 JFL Created this module. *
* 2014-07-03 JFL Added support for pathnames >= 260 characters. *
* *
* Copyright 2016 Hewlett Packard Enterprise Development LP *
* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 *
\*****************************************************************************/
#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */
/* Microsoft C libraries include files */
#include <stdio.h>
/* MsvcLibX library extensions */
#include "msvcDebugm.h"
#include "msvclibx.h"
#include "msvcLimits.h"
#ifdef _WIN32
#include <windows.h>
#include <process.h>
/*---------------------------------------------------------------------------*\
* *
| Function _spawnvpU |
| |
| Description UTF-8 version of Microsoft's _spawnvp |
| |
| Parameters: int iMode Spawning mode. P_WAIT or P_NOWAIT |
| char *pszCommand Program to start |
| char **argv List of arguments, terminated by NULL |
| |
| Returns: The exit code (if P_WAIT) or the process ID (if P_NOWAIT) |
| |
| Notes |
| |
| History |
| 2014-03-04 JFL Created this routine. |
* *
\*---------------------------------------------------------------------------*/
intptr_t _spawnvpU(int iMode, const char *pszCommand, char *const *argv) {
WCHAR wszCommand[PATH_MAX];
WCHAR **wszArgv;
int n;
int nArgs;
int iArg;
intptr_t iRet;
DEBUG_CODE({
int i;
DEBUG_PRINTF(("_spawnvpU(%d, \"%s\", {", iMode, pszCommand));
if (DEBUG_IS_ON()) {
for (i=0; argv[i]; i++) {
if (i) printf(", ");
printf("\"%s\"", argv[i]);
}
printf("});\n");
}
})
/* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */
n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */
pszCommand, /* lpMultiByteStr, */
wszCommand, /* lpWideCharStr, */
COUNTOF(wszCommand) /* cchWideChar, */
);
if (!n) {
errno = Win32ErrorToErrno();
return -1;
}
for (nArgs=0; argv[nArgs]; nArgs++) ; /* Count the number of arguments */
wszArgv = (WCHAR **)malloc((nArgs+1) * sizeof(WCHAR *));
if (!wszArgv) return -1; /* errno already set by malloc */
for (iArg=0; argv[iArg]; iArg++) { /* Convert every argument */
int iArgBufSize = lstrlen(argv[iArg]) + 1;
wszArgv[iArg] = malloc(sizeof(WCHAR)*iArgBufSize);
if (!wszArgv[iArg]) {
while (iArg) free(wszArgv[--iArg]); /* Free the partial arg list */
free(wszArgv);
return -1; /* errno already set by malloc */
}
/* Convert the argument to a unicode string. This is not a pathname, so just do a plain conversion */
n = MultiByteToWideChar(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */
0, /* dwFlags, */
argv[iArg], /* lpMultiByteStr, */
iArgBufSize, /* cbMultiByte, */
wszArgv[iArg], /* lpWideCharStr, */
iArgBufSize /* cchWideChar, */
);
if (!n) {
errno = Win32ErrorToErrno();
while (iArg >= 0) free(wszArgv[iArg--]); /* Free the partial arg list */
free(wszArgv);
return -1;
}
}
wszArgv[nArgs] = NULL;
iRet = _wspawnvp(iMode, wszCommand, wszArgv);
while (nArgs) free(wszArgv[--nArgs]); /* Free the full arg list */
free(wszArgv);
return iRet;
}
#endif /* defined(_WIN32) */