gpt4 book ai didi

c++ - 用于列出正在运行的进程的 Linux API? - 有论点

转载 作者:太空狗 更新时间:2023-10-29 20:30:02 27 4
gpt4 key购买 nike

这篇文章几乎回答了我的问题: Linux API to list running processes?

但是示例代码(C++/C - 见下文)中缺少的是进程的参数。例如,名为 mypaint 的程序将仅列为“python2.7”,而不是完整的可执行文件和参数“python2.7/usr/bin/mypaint”。

来自 proc 的手册页:/proc/[pid]/cmdline这包含进程的完整命令行,除非进程是僵尸进程。在后一种情况下,此文件中没有任何内容:也就是说,读取此文件将返回 0 个字符。命令行参数在此文件中显示为一组由空字节 ('\0') 分隔的字符串,最后一个字符串后还有一个空字节。

如何修改此代码以同时列出进程的参数?

#ifndef __cplusplus
#define _GNU_SOURCE
#endif

#include <unistd.h>
#include <dirent.h>
#include <sys/types.h> // for opendir(), readdir(), closedir()
#include <sys/stat.h> // for stat()

#ifdef __cplusplus
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdarg>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#endif


#define PROC_DIRECTORY "/proc/"
#define CASE_SENSITIVE 1
#define CASE_INSENSITIVE 0
#define EXACT_MATCH 1
#define INEXACT_MATCH 0


int IsNumeric(const char* ccharptr_CharacterList)
{
for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++)
if (*ccharptr_CharacterList < '0' || *ccharptr_CharacterList > '9')
return 0; // false
return 1; // true
}


int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive)
{
if (intCaseSensitive)
return !strcmp(s1, s2);
else
return !strcasecmp(s1, s2);
}

int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive)
{
if (intCaseSensitive)
return (int) strstr(haystack, needle);
else
return (int) strcasestr(haystack, needle);
}


#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#else
pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#endif
{
char chrarry_CommandLinePath[100] ;
char chrarry_NameOfProcess[300] ;
char* chrptr_StringToCompare = NULL ;
pid_t pid_ProcessIdentifier = (pid_t) -1 ;
struct dirent* de_DirEntity = NULL ;
DIR* dir_proc = NULL ;

int (*CompareFunction) (const char*, const char*, int) ;

if (intExactMatch)
CompareFunction = &strcmp_Wrapper;
else
CompareFunction = &strstr_Wrapper;


dir_proc = opendir(PROC_DIRECTORY) ;
if (dir_proc == NULL)
{
perror("Couldn't open the " PROC_DIRECTORY " directory") ;
return (pid_t) -2 ;
}

// Loop while not NULL
while ( (de_DirEntity = readdir(dir_proc)) )
{
if (de_DirEntity->d_type == DT_DIR)
{
if (IsNumeric(de_DirEntity->d_name))
{
strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ;
strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ;
strcat(chrarry_CommandLinePath, "/cmdline") ;
FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ; // open the file for reading text
if (fd_CmdLineFile)
{
fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; // read from /proc/<NR>/cmdline
fclose(fd_CmdLineFile); // close the file prior to exiting the routine

if (strrchr(chrarry_NameOfProcess, '/'))
chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ;
else
chrptr_StringToCompare = chrarry_NameOfProcess ;

printf("Process name: %s\n", chrarry_NameOfProcess);
printf("Pure Process name: %s\n", chrptr_StringToCompare );

if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) )
{
pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ;
closedir(dir_proc) ;
return pid_ProcessIdentifier ;
}
}
}
}
}
closedir(dir_proc) ;
return pid_ProcessIdentifier ;
}

#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName)
{
return GetPIDbyName(cchrptr_ProcessName, CASE_INSENSITIVE, EXACT_MATCH) ;
}
#else
// C cannot overload functions - fixed
pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName, ... )
{
int intTempArgument ;
int intInputArguments[2] ;
// intInputArguments[0] = 0 ;
// intInputArguments[1] = 0 ;
memset(intInputArguments, 0, sizeof(intInputArguments) ) ;
int intInputIndex ;
va_list argptr;

va_start( argptr, cchrptr_ProcessName );
for (intInputIndex = 0; (intTempArgument = va_arg( argptr, int )) != 15; ++intInputIndex)
{
intInputArguments[intInputIndex] = intTempArgument ;
}
va_end( argptr );
return GetPIDbyName_implements(cchrptr_ProcessName, intInputArguments[0], intInputArguments[1]);
}

#define GetPIDbyName(ProcessName,...) GetPIDbyName_Wrapper(ProcessName, ##__VA_ARGS__, (int) 15)

#endif

int main()
{
pid_t pid = GetPIDbyName("bash") ; // If -1 = not found, if -2 = proc fs access error
printf("PID %d\n", pid);
return EXIT_SUCCESS ;
}

(chrarry_NameOfProcess = 仅可执行如何显示参数)?

最佳答案

假设您真的不想分别解析每个参数,而只想像您当前所做的那样打印它们,一个简单的方法是:

(1) 用fread代替fscanf,读取任意大的字节数。 (或者先找到文件长度,然后读取数量,如果您想专业地执行此操作。)这会将包括空字节在内的所有内容读取到您的缓冲区中。

(2) 遍历缓冲区,用空格替换空值。

(3) 在读取的字节末尾放一个null来终止字符串。

(4) 然后打印出来。

所以在你的 GetPIDbyName() 函数中是这样的:

const int BUFFERSIZE = 300;
int bytesread;
char chrarry_NameOfProcess[BUFFERSIZE] ;

//...........

FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rb") ;

if (fd_CmdLineFile)
{
//fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ;
bytesread = fread(chrarry_NameOfProcess, 1, BUFFERSIZE, fd_CmdLineFile);

for (int i = 0; i < bytesread; ++i)
if (chrarry_NameOfProcess[i] == '\0')
chrarry_NameOfProcess[i] = ' ';

chrarry_NameOfProcess[bytesread] = '\0';

fclose(fd_CmdLineFile);

//... the rest
}

关于c++ - 用于列出正在运行的进程的 Linux API? - 有论点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8249146/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com