API do Linux para listar processos em execução?

Eu preciso de uma API C / C ++ que me permita listar os processos em execução em um sistema Linux e listar os arquivos que cada processo abriu.

Eu não quero acabar lendo o sistema de arquivos / proc / diretamente.

Alguém pode pensar em uma maneira de fazer isso?

http://procps.sourceforge.net/

http://procps.cvs.sourceforge.net/viewvc/procps/procps/proc/readproc.c?view=markup

É a fonte de ps e outras ferramentas de processo. Eles realmente usam proc (indicando que é provavelmente a maneira convencional e melhor). Sua fonte é bastante legível. O arquivo

/procps-3.2.8/proc/readproc.c 

Pode ser útil. Também uma sugestão útil como postada pelo ephemient está ligando para a API fornecida pelo libproc , que deve estar disponível em seu repo (ou já instalado, eu diria), mas você precisará da variação “-dev” para os headers e o que não.

Boa sorte

Se você não quer ler de ‘/ proc. Então você pode considerar escrever um módulo do Kernel que implementará sua própria chamada de sistema. E sua chamada de sistema deve ser escrita para que possa obter a lista de processos atuais, como:

 /* ProcessList.c Robert Love Chapter 3 */ #include < linux/kernel.h > #include < linux/sched.h > #include < linux/module.h > int init_module(void) { struct task_struct *task; for_each_process(task) { printk("%s [%d]\n",task->comm , task->pid); } return 0; } void cleanup_module(void) { printk(KERN_INFO "Cleaning Up.\n"); } 

O código acima é retirado do meu artigo aqui em http://linuxgazette.net/133/saha.html. Depois de ter sua própria chamada de sistema, você pode chamar de seu programa de espaço do usuário.

Se você não fizer isso, então eu acho que qualquer API que você usar irá acabar lendo o sistema de arquivos / proc. Aqui estão alguns exemplos de programa fazendo isso:

  • qps
  • htop
  • procps

Mas infelizmente, isso não constitui uma API.

Aqui você vai (C / C ++):

Você poderia ter encontrado aqui: http://ubuntuforums.org/showthread.php?t=657097

 #ifndef __cplusplus #define _GNU_SOURCE #endif #include  #include  #include  // for opendir(), readdir(), closedir() #include  // for stat() #ifdef __cplusplus #include  #include  #include  #include  #else #include  #include  #include  #include  #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//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 ; } 

PS e todas as outras ferramentas (EXCEPT for Kernel Modules) lidas de /proc . /proc é um sistema de arquivos especial criado em tempo real pelo kernel, para que os processos no modo usuário possam ler dados que, de outra forma, só estarão disponíveis para o kernel.

A maneira recomendada é, portanto, ler a partir de /proc .

Você pode rapidamente olhar intuitivamente para o sistema de arquivos /proc para ver como está estruturado. Para cada processo existe um /proc/pid onde pid é o número de identificação do processo. Dentro desta pasta existem vários arquivos que incluem dados diferentes sobre o processo atual. Se você correr

 strace ps -aux 

você verá como o programa ps lê esses dados de /proc .

A única maneira de fazer isso sem ler / proc seria chamar “ps aux”, passar por todas as linhas, ler a segunda coluna (o PID) e chamar lsof -p [PID] com ele.

… sugiro ler / proc;)

Há uma biblioteca libprocps do projeto procps-ng . No Ubuntu 13.04, se você fizer strace ps , então você pode ver que o ps usa o libprocps .

Leitura proc não é tão ruim. Eu não posso te mostrar em C ++, mas o seguinte código D deve apontar na direção certa:

 import std.stdio;
 import std.string;
 import std.file;
 import std.regexp;
 importar std.c.linux.linux;

 alias std.string.split explode;

 string srex = "^ / proc / [0-9] + $";
 string trex = "Estado: [\ t] [SR]";
 RegExp rex;
 RegExp rext;

    string [] scanPidDirs (alvo da string)
    {
       string [] resultado;

       retorno de chamada de bool (DirEntry * de)
       {
          if (de.isdir)
          {
             if (rex.find (de.name)> = 0)
             {
                 string [] a = explode (de.name, "/");
                 string pid = a [comprimento-1];
                 string x = casting (string) std.file.read (de.name ~ "/ status");
                 int n = rext.find (x);
                 if (n> = 0)
                 {
                     x = cast (string) std.file.read (de.name ~ "/ cmdline");
                     // Isso é terminado em null
                     if (x.length) x.length = x.length-1;
                     a = explode (x, "/");
                     if (a.length)
                        x = a [comprimento-1];
                     outro
                        x = "";
                      if (x = = alvo)
                     {
                         resultado ~ = pid ~ "/" ~ x;
                     }
                 }
              }
           }
           retorno verdadeiro;
       }

       listdir ("/ proc", & callback);
       return result.dup;
    }

 void main (string [] args)
 {
     rex = new RegExp (srex);
     rext = new RegExp (trex);
     string [] a = scanPidDirs (args [1]);
     if (! a.length)
     {
         writefln ("Não encontrado");
         Retorna;
     }
     writefln ("% d processos correspondentes", a.length);
     foreach (s; a)
     {
        string [] p = explode (s, "/");
        int pid = atoi (p [0]);
        writef ("Parar% s (% d)?", s, pid);
        string r = readln ();
        if (r == "Y \ n" || r == "y \ n")
           matar (pid, SIGUSR1);
     }
 }

Maneira fácil de fin pid de qualquer processo pelo nome

 pid_t GetPIDbyName(char* ps_name) { FILE *fp; char *cmd=(char*)calloc(1,200); sprintf(cmd,"pidof %s",ps_name); fp=popen(cmd,"r"); fread(cmd,1,200,fp); fclose(fp); return atoi(cmd); }