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; }
static Bool ReadArgsFromAddressSpaceFile(FileIODescriptor asFd, //IN psinfo_t *psInfo, //IN DynBufArray *cmdLineArr) //OUT { uintptr_t *argOffs; uintptr_t argOff; uintptr_t nextArgOff; int argc; int i; char *argBuf; char *argBufPtr; DynBuf *arg; argc = psInfo->pr_argc; DynBufArray_Init(cmdLineArr, argc); for (i = 0; i < argc; i++) { DynBuf_Init(DynBufArray_AddressOf(cmdLineArr, i)); } if (argc == 0) { return TRUE; } argOffs = Util_SafeCalloc(argc, sizeof *argOffs); if (argOffs == NULL) { return FALSE; } if (!ReadOffsetsFromAddressSpaceFile(asFd, psInfo, argOffs)) { goto fail; } /* Read the command line arguments into the cmdLineArr array. */ nextArgOff = argc > 0 ? argOffs[0] : 0; i = 0; while (i < argc) { argOff = argOffs[i]; /* * The argument strings are contiguous in the address space file. So * argOff[i] + strlen(arg[i]) + 1 should be equal to argOff[i + 1]. */ if ((argOff == 0) || (argOff != nextArgOff)) { goto fail; } argBuf = ExtractArgStringFromAddressSpaceFile(asFd, argOff); if (argBuf == NULL) { goto fail; } nextArgOff = argOff + strlen(argBuf) + 1; argBufPtr = argBuf + strlen(argBuf); while ((argBufPtr > argBuf) && isspace(*(argBufPtr - 1))) { argBufPtr--; } *argBufPtr = '\0'; arg = DynBufArray_AddressOf(cmdLineArr, i); if (!DynBuf_Append(arg, argBuf, strlen(argBuf) + 1)) { free(argBuf); goto fail; } free(argBuf); i++; } return TRUE; fail: Warning("Failed to read command line arguments\n"); argc = DynBufArray_Count(cmdLineArr); for (i = 0; i < argc; i++) { arg = DynArray_AddressOf(cmdLineArr, i); DynBuf_Destroy(arg); } DynBufArray_SetCount(cmdLineArr, 0); DynBufArray_Destroy(cmdLineArr); free(argOffs); return FALSE; }
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; }