API de Linux para mostrar los procesos en ejecución?

Necesito una API de C / C ++ que me permita enumerar los procesos en ejecución en un sistema Linux y enumerar los archivos que cada proceso tiene abiertos.

No quiero terminar leyendo el sistema / proc / file directamente.

¿Alguien puede pensar en una forma de hacer esto?

http://procps.sourceforge.net/

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

Es la fuente de ps y otras herramientas de proceso. De hecho, usan proc (lo que indica que es probablemente la mejor manera convencional). Su fuente es bastante legible. El archivo

/procps-3.2.8/proc/readproc.c 

Puede ser útil. También una sugerencia útil publicada por ephemient es enlazar a la API proporcionada por libproc , que debería estar disponible en su repository (o ya instalado, diría) pero necesitará la variación “-dev” para los encabezados y lo que no.

Buena suerte

Si no quieres leer de ‘/ proc. Luego puede considerar escribir un módulo Kernel que implementará su propia llamada al sistema. Y su llamada al sistema debe escribirse para que pueda obtener la lista de procesos actuales, 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"); } 

El código anterior está tomado de mi artículo aquí en http://linuxgazette.net/133/saha.html. Una vez que tenga su propia llamada al sistema, puede llamar desde su progtwig de espacio de usuario.

Si no lo haces, entonces supongo que cualquier API que uses terminará leyendo el sistema de archivos / proc. Aquí hay algunos ejemplos de progtwigs que hacen esto:

  • qps
  • htop
  • procps

Pero desafortunadamente, eso no constituye una API.

Aquí tienes (C / C ++):

Podrías haberlo encontrado aquí: 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 y cualquier otra herramienta (EXCEPTO para Kernel Modules) lectura de /proc . /proc es un sistema de archivos especial creado sobre la marcha por el kernel para que los procesos en modo usuario puedan leer datos que de otro modo solo estarían disponibles para el kernel.

La forma recomendada es, por lo tanto, leer de /proc .

Puedes mirar intuitivamente el sistema de archivos /proc para ver cómo está estructurado. Para cada proceso hay un /proc/pid donde pid es el número de identificación del proceso. Dentro de esta carpeta hay varios archivos que incluyen diferentes datos sobre el proceso actual. Si tu corres

 strace ps -aux 

Verás cómo el progtwig ps lee estos datos de /proc .

La única forma de hacerlo sin leer / proc sería llamar a “ps aux”, recorrer cada línea, leer la segunda columna (el PID) y llamar a lsof -p [PID] con ella.

… Sugeriría leer / proc;)

Hay una biblioteca libprocps del proyecto libprocps procps-ng . En Ubuntu 13.04, si haces strace ps , entonces puedes ver que ps usa libprocps .

El proceso de lectura no es tan malo. No puedo mostrarle en C ++, pero el siguiente código D debe indicarle la dirección correcta:

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

 alias std.string.split explotar;

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

    string [] scanPidDirs (string target)
    {
       string [] resultado;

       bool callback (DirEntry * de)
       {
          if (de.isdir)
          {
             if (rex.find (de.name)> = 0)
             {
                 string [] a = explode (de.name, "/");
                 cadena pid = a [a.length-1];
                 string x = cast (string) std.file.read (de.name ~ "/ status");
                 int n = rext.find (x);
                 if (n> = 0)
                 {
                     x = cast (string) std.file.read (de.name ~ "/ cmdline");
                     // Esto es nulo terminado
                     if (x.length) x.length = x.length-1;
                     a = explotar (x, "/");
                     si (a.length)
                        x = a [a.length-1];
                     más
                        x = "";
                      if (x == target)
                     {
                         resultado ~ = pid ~ "/" ~ x;
                     }
                 }
              }
           }
           devolver verdadero;
       }

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

 void main (string [] args)
 {
     rex = nuevo RegExp (srex);
     rext = new RegExp (trex);
     string [] a = scanPidDirs (args [1]);
     si (! a.length)
     {
         writefln ("No encontrado");
         regreso;
     }
     writefln ("% d matching processes", a.length);
     foreach (s; a)
     {
        cadena [] p = explosión (s, "/");
        int pid = atoi (p [0]);
        writef ("Stop% s (% d)?", s, pid);
        cadena r = readln ();
        if (r == "Y \ n" || r == "y \ n")
           kill (pid, SIGUSR1);
     }
 }

Manera fácil de fin pid de cualquier proceso por nombre

 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); }