From: Oliver Kurth Date: Mon, 17 Jun 2019 18:41:36 +0000 (-0700) Subject: Improvements for ProcMgr library. X-Git-Tag: stable-11.0.0~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5260daab25ee9afdd5267531516b45f5006d57d1;p=thirdparty%2Fopen-vm-tools.git Improvements for ProcMgr library. * This changeset fixes various issues related to ProcMgr library. == Retrieve the absolute path of the image for each process == * When listing down the processes, it is useful to retrieve the absolute path of the process binary. === For Linux ===: * In /proc filesystem, /proc/{PID}/exe is a symlink to the binary and we can make use of it to figure out the absolute path. * If /proc/{PID}/exe is not a valid symlink, then the 'cmdline' is parsed and aboslute path is calculated accordingly. * Note: This changeset tries its best to figure out the absolute path. If it can't, then the attribute is set to NULL. == Misc issues fixed. == === Linux === * Fixed a memory leak with 'procCmdName' while looping through the /proc/ directory entries. * Fixed another memory leak with cmdLineTemp and cmdStatTemp variables while listing down the processes in linux guests. * In few cases, /proc/{PID}/cmdline file contains multiple NUL characters at the end. In that case, the existing code converts them into 'whitespaces'. Fixed the code to chop of all the trailing whitespaces in the command line. --- diff --git a/open-vm-tools/lib/include/procMgr.h b/open-vm-tools/lib/include/procMgr.h index e6c0a62ec..d6adad1ba 100644 --- a/open-vm-tools/lib/include/procMgr.h +++ b/open-vm-tools/lib/include/procMgr.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2002-2017 VMware, Inc. All rights reserved. + * Copyright (C) 2002-2019 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -56,6 +56,9 @@ typedef struct ProcMgr_AsyncProc ProcMgr_AsyncProc; typedef struct ProcMgrProcInfo { ProcMgr_Pid procId; char *procCmdName; // UTF-8 +#if defined(__linux__) || defined(_WIN32) + char *procCmdAbsPath; // UTF-8 +#endif char *procCmdLine; // UTF-8 char *procOwner; // UTF-8 #if defined(_WIN32) @@ -134,6 +137,11 @@ typedef int Selectable; #endif ProcMgrProcInfoArray *ProcMgr_ListProcesses(void); + +#if defined(_WIN32) +ProcMgrProcInfoArray *ProcMgr_ListProcessesEx(void); +#endif + void ProcMgr_FreeProcList(ProcMgrProcInfoArray *procList); Bool ProcMgr_KillByPid(ProcMgr_Pid procId); diff --git a/open-vm-tools/lib/procMgr/procMgrPosix.c b/open-vm-tools/lib/procMgr/procMgrPosix.c index 97c995900..e2cd0619f 100644 --- a/open-vm-tools/lib/procMgr/procMgrPosix.c +++ b/open-vm-tools/lib/procMgr/procMgrPosix.c @@ -258,6 +258,7 @@ ProcMgr_ListProcesses(void) procList = Util_SafeCalloc(1, sizeof *procList); ProcMgrProcInfoArray_Init(procList, 0); procInfo.procCmdName = NULL; + procInfo.procCmdAbsPath = NULL; procInfo.procCmdLine = NULL; procInfo.procOwner = NULL; @@ -386,6 +387,21 @@ ProcMgr_ListProcesses(void) continue; } + if (snprintf(cmdFilePath, + sizeof cmdFilePath, + "/proc/%s/exe", + ent->d_name) != -1) { + int exeLen; + char exeRealPath[1024]; + + exeLen = readlink(cmdFilePath, exeRealPath, sizeof exeRealPath -1); + if (exeLen != -1) { + exeRealPath[exeLen] = '\0'; + procInfo.procCmdAbsPath = + Unicode_Alloc(exeRealPath, STRING_ENCODING_DEFAULT); + } + } + if (numRead > 0) { for (replaceLoop = 0 ; replaceLoop < numRead ; replaceLoop++) { if ('\0' == cmdLineTemp[replaceLoop]) { @@ -405,6 +421,11 @@ ProcMgr_ListProcesses(void) cmdNameBegin++; } procInfo.procCmdName = Unicode_Alloc(cmdNameBegin, STRING_ENCODING_DEFAULT); + if (procInfo.procCmdAbsPath != NULL && + cmdLineTemp[0] == '/') { + procInfo.procCmdAbsPath = + Unicode_Alloc(cmdLineTemp, STRING_ENCODING_DEFAULT); + } cmdNameLookup = FALSE; } @@ -470,6 +491,10 @@ ProcMgr_ListProcesses(void) * Store the command name. */ procInfo.procCmdName = Unicode_Alloc(cmdLineTemp, STRING_ENCODING_DEFAULT); + if (procInfo.procCmdAbsPath != NULL && + cmdLineTemp[0] == '/') { + procInfo.procCmdAbsPath = Unicode_Alloc(cmdLineTemp, STRING_ENCODING_DEFAULT); + } } } @@ -543,6 +568,17 @@ ProcMgr_ListProcesses(void) * Store the command line string pointer in dynbuf. */ if (cmdLineTemp) { + int i; + + /* + * Chop off the trailing whitespace characters. + */ + for (i = strlen(cmdLineTemp) - 1 ; + i >= 0 && cmdLineTemp[i] == ' ' ; + i--) { + cmdLineTemp[i] = '\0'; + } + procInfo.procCmdLine = Unicode_Alloc(cmdLineTemp, STRING_ENCODING_DEFAULT); } else { procInfo.procCmdLine = Unicode_Alloc("", STRING_ENCODING_UTF8); @@ -572,13 +608,21 @@ ProcMgr_ListProcesses(void) if (!ProcMgrProcInfoArray_Push(procList, procInfo)) { Warning("%s: failed to expand DynArray - out of memory\n", __FUNCTION__); + free(cmdLineTemp); + free(cmdStatTemp); goto abort; } procInfo.procCmdName = NULL; + procInfo.procCmdAbsPath = NULL; procInfo.procCmdLine = NULL; procInfo.procOwner = NULL; next_entry: + free(procInfo.procCmdName); + procInfo.procCmdName = NULL; + free(procInfo.procCmdAbsPath); + procInfo.procCmdAbsPath = NULL; + free(cmdLineTemp); free(cmdStatTemp); } // while readdir @@ -591,6 +635,7 @@ abort: closedir(dir); free(procInfo.procCmdName); + free(procInfo.procCmdAbsPath); free(procInfo.procCmdLine); free(procInfo.procOwner); @@ -1195,6 +1240,9 @@ ProcMgr_FreeProcList(ProcMgrProcInfoArray *procList) for (i = 0; i < procCount; i++) { ProcMgrProcInfo *procInfo = ProcMgrProcInfoArray_AddressOf(procList, i); free(procInfo->procCmdName); +#if defined(__linux__) + free(procInfo->procCmdAbsPath); +#endif free(procInfo->procCmdLine); free(procInfo->procOwner); }