static char * ExtractCommandLineFromAddressSpaceFile(psinfo_t *procInfo) //IN: psinfo struct { int argc; int i; char tempPath[MAXPATHLEN]; char *buf; FileIODescriptor asFd; FileIOResult res; DynBuf cmdLine; DynBufArray args; pid_t pid; FileIO_Invalidate(&asFd); pid = procInfo->pr_pid; if (Str_Snprintf(tempPath, sizeof tempPath, "/proc/%"FMT64"d/as", (int64_t)pid) == -1) { /* This should not happen. MAXPATHLEN should be large enough. */ ASSERT(FALSE); } res = FileIO_Open(&asFd, tempPath, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (res != FILEIO_SUCCESS) { Warning("Could not open address space file for pid %"FMT64"d, %s\n", (int64_t)pid, FileIO_MsgError(res)); return NULL; } buf = NULL; if (ReadArgsFromAddressSpaceFile(asFd, procInfo, &args)) { /* Concatenate the strings in args into cmdLine. */ DynBuf_Init(&cmdLine); argc = DynBufArray_Count(&args); for (i = 0; i < argc; i++) { buf = DynBuf_Get(DynBufArray_AddressOf(&args, i)); DynBuf_Append(&cmdLine, buf, strlen(buf)); if (i + 1 < argc) { DynBuf_Append(&cmdLine, " ", 1); } DynBuf_Destroy(DynBufArray_AddressOf(&args, i)); } DynBuf_AppendString(&cmdLine,""); DynBufArray_Destroy(&args); DynBuf_Trim(&cmdLine); buf = DynBuf_Detach(&cmdLine); DynBuf_Destroy(&cmdLine); } FileIO_Close(&asFd); return buf; }
VixError VixToolsEnvironToEnvBlock(char const * const *environ, // IN: UTF-8 wchar_t **envBlock) // OUT { VixError err; DynBuf buf; Bool res; static const wchar_t nullTerm[] = { L'\0', L'\0' }; DynBuf_Init(&buf); if ((NULL == environ) || (NULL == envBlock)) { err = VIX_E_FAIL; goto abort; } *envBlock = NULL; while (NULL != *environ) { wchar_t *envVar = Unicode_GetAllocUTF16(*environ); res = DynBuf_Append(&buf, envVar, (wcslen(envVar) + 1) * sizeof(*envVar)); free(envVar); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } environ++; } /* * Append two null characters at the end. This adds an extra (third) null * if there was at least one environment variable (since there already * is one after the last string) but we need both if there were no * environment variables in the input array. I'll waste two bytes to * keep the code a little simpler. */ res = DynBuf_Append(&buf, nullTerm, sizeof nullTerm); if (!res) { err = VIX_E_OUT_OF_MEMORY; goto abort; } *envBlock = DynBuf_Detach(&buf); err = VIX_OK; abort: DynBuf_Destroy(&buf); return err; }
char * Hostinfo_GetCpuidStr(void) { static const uint32 basic_args[] = {0x0, 0x1, 0xa}; static const uint32 extended_args[] = {0x80000000, 0x80000001, 0x80000008}; DynBuf buf; char *result; DynBuf_Init(&buf); HostInfoGetCpuidStrSection(basic_args, ARRAYSIZE(basic_args), &buf); HostInfoGetCpuidStrSection(extended_args, ARRAYSIZE(extended_args), &buf); // Trim buffer and set NULL character to replace last '-'. DynBuf_Trim(&buf); result = (char*)DynBuf_Get(&buf); ASSERT(result && result[0]); // We should at least get result from eax = 0x0. result[DynBuf_GetSize(&buf) - 1] = '\0'; return DynBuf_Detach(&buf); }
Bool CodeSet_Init(const char *icuDataDir) // IN: ICU data file location in Current code page. // Default is used if NULL. { DynBuf dbpath; #ifdef _WIN32 DWORD attribs; utf16_t *modPath = NULL; utf16_t *lastSlash; utf16_t *wpath; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping = NULL; void *memMappedData = NULL; #else struct stat finfo; #endif char *path = NULL; Bool ret = FALSE; DynBuf_Init(&dbpath); #ifdef USE_ICU /* * We're using system ICU, which finds its own data. So nothing to * do here. */ dontUseIcu = FALSE; ret = TRUE; goto exit; #endif /* * ********************* WARNING * Must avoid recursive calls into the codeset library here, hence * the idiotic hoop-jumping. DO NOT change any of these calls to * wrapper equivalents or call any other functions that may perform * string conversion. * ********************* WARNING */ #ifdef _WIN32 // { #if vmx86_devel /* * Devel builds use toolchain directory first. */ { WCHAR icuFilePath[MAX_PATH] = { 0 }; DWORD n = ExpandEnvironmentStringsW(ICU_DATA_FILE_PATH, icuFilePath, ARRAYSIZE(icuFilePath)); if (n > 0 && n < ARRAYSIZE(icuFilePath)) { attribs = GetFileAttributesW(icuFilePath); if ((INVALID_FILE_ATTRIBUTES != attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY) == 0) { if (!CodeSetOld_Utf16leToCurrent((const char *) icuFilePath, n * sizeof *icuFilePath, &path, NULL)) { goto exit; } goto found; } } } #endif if (icuDataDir) { /* * Data file must be in the specified directory. */ size_t length = strlen(icuDataDir); if (!DynBuf_Append(&dbpath, icuDataDir, length)) { goto exit; } if (length && icuDataDir[length - 1] != DIRSEPC) { if (!DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS))) { goto exit; } } if (!DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. */ attribs = GetFileAttributesA(DynBuf_Get(&dbpath)); if ((INVALID_FILE_ATTRIBUTES == attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY)) { goto exit; } path = (char *) DynBuf_Detach(&dbpath); } else { /* * Data file must be in the directory of the current module * (i.e. the module that contains CodeSet_Init()). */ HMODULE hModule = W32Util_GetModuleByAddress((void *) CodeSet_Init); if (!hModule) { goto exit; } modPath = CodeSetGetModulePath(hModule); if (!modPath) { goto exit; } lastSlash = wcsrchr(modPath, DIRSEPC_W); if (!lastSlash) { goto exit; } *lastSlash = L'\0'; if (!DynBuf_Append(&dbpath, modPath, wcslen(modPath) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, DIRSEPS_W, wcslen(DIRSEPS_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE_W, wcslen(ICU_DATA_FILE_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, L"\0", 2)) { goto exit; } /* * Since u_setDataDirectory can't handle UTF-16, we would have to * now convert this path to local encoding. But that fails when * the module is in a path containing characters not in the * local encoding (see 282524). So we'll memory-map the file * instead and call udata_setCommonData() below. */ wpath = (utf16_t *) DynBuf_Get(&dbpath); hFile = CreateFileW(wpath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) { goto exit; } hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (NULL == hMapping) { goto exit; } memMappedData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (NULL == memMappedData) { goto exit; } } #else // } _WIN32 { #if vmx86_devel { char *modPath; char *lastSlash; /* * Devel builds use toolchain directory first. */ if (stat(ICU_DATA_FILE_PATH, &finfo) >= 0 && !S_ISDIR(finfo.st_mode)) { if ((path = strdup(ICU_DATA_FILE_PATH)) == NULL) { goto exit; } goto found; } /* * Then we try module directory, if we can get it. */ modPath = CodeSetGetModulePath(HGMP_PRIVILEGE); if (modPath) { lastSlash = strrchr(modPath, DIRSEPC); if (lastSlash) { *lastSlash = '\0'; if (DynBuf_Append(&dbpath, modPath, strlen(modPath)) && DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) && DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) && DynBuf_Append(&dbpath, "\0", 1)) { if ((stat((const char *) DynBuf_Get(&dbpath), &finfo) >= 0) && !S_ISDIR(finfo.st_mode)) { free(modPath); path = DynBuf_Detach(&dbpath); goto found; } else { DynBuf_SetSize(&dbpath, 0); } } } free(modPath); } } #endif // vmx86_devel /* * Data file is either in POSIX_ICU_DIR or user specified dir. */ if (!icuDataDir) { icuDataDir = POSIX_ICU_DIR; } if (!DynBuf_Append(&dbpath, icuDataDir, strlen(icuDataDir)) || !DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. (DO NOT CHANGE TO 'stat' WRAPPER). */ path = (char *) DynBuf_Detach(&dbpath); if (stat(path, &finfo) < 0 || S_ISDIR(finfo.st_mode)) { goto exit; } #endif // } _WIN32 #if vmx86_devel found: #endif #ifdef _WIN32 if (memMappedData) { /* * Tell ICU to use this mapped data. */ UErrorCode uerr = U_ZERO_ERROR; ASSERT(memMappedData); udata_setCommonData(memMappedData, &uerr); if (uerr != U_ZERO_ERROR) { UnmapViewOfFile(memMappedData); goto exit; } } else { #endif /* * Tell ICU to use this directory. */ u_setDataDirectory(path); #ifdef _WIN32 } #endif dontUseIcu = FALSE; ret = TRUE; exit: if (!ret) { /* * There was an error initing ICU, but if we can fall back on * non-ICU (old CodeSet) then things are OK. */ if (CODESET_CAN_FALLBACK_ON_NON_ICU) { ret = TRUE; dontUseIcu = TRUE; #ifdef _WIN32 OutputDebugStringW(L"CodeSet_Init: no ICU\n"); #endif } } #ifdef _WIN32 free(modPath); if (hMapping) { CloseHandle(hMapping); } if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } #endif free(path); DynBuf_Destroy(&dbpath); return ret; }
static char * ExtractCommandLineFromAddressSpaceFile(psinfo_t *procInfo, //IN: psinfo struct char **procCmdName) //OUT: command name { int argc; int i; char tempPath[MAXPATHLEN]; char *buf; FileIODescriptor asFd; FileIOResult res; DynBuf cmdLine; DynBufArray args; pid_t pid; char *cmdNameBegin; if (NULL != procCmdName) { *procCmdName = NULL; } FileIO_Invalidate(&asFd); pid = procInfo->pr_pid; if (Str_Snprintf(tempPath, sizeof tempPath, "/proc/%"FMT64"d/as", (int64_t)pid) == -1) { /* This should not happen. MAXPATHLEN should be large enough. */ ASSERT(FALSE); } res = FileIO_Open(&asFd, tempPath, FILEIO_OPEN_ACCESS_READ, FILEIO_OPEN); if (res != FILEIO_SUCCESS) { Warning("Could not open address space file for pid %"FMT64"d, %s\n", (int64_t)pid, FileIO_MsgError(res)); return NULL; } buf = NULL; if (ReadArgsFromAddressSpaceFile(asFd, procInfo, &args)) { /* Concatenate the strings in args into cmdLine. */ DynBuf_Init(&cmdLine); argc = DynBufArray_Count(&args); for (i = 0; i < argc; i++) { buf = DynBuf_Get(DynBufArray_AddressOf(&args, i)); DynBuf_Append(&cmdLine, buf, strlen(buf)); if (i + 1 < argc) { DynBuf_Append(&cmdLine, " ", 1); } if (NULL != procCmdName && 0 == i) { /* * Store the command name of the process. * Find the last path separator, to get the cmd name. * If no separator is found, then use the whole name. */ cmdNameBegin = strrchr(buf, '/'); if (NULL == cmdNameBegin) { cmdNameBegin = buf; } else { /* * Skip over the last separator. */ cmdNameBegin++; } *procCmdName = Unicode_Alloc(cmdNameBegin, STRING_ENCODING_DEFAULT); } DynBuf_Destroy(DynBufArray_AddressOf(&args, i)); } DynBuf_AppendString(&cmdLine,""); DynBufArray_Destroy(&args); DynBuf_Trim(&cmdLine); buf = DynBuf_Detach(&cmdLine); DynBuf_Destroy(&cmdLine); } FileIO_Close(&asFd); return buf; }