it-swarm.com.de

Linux-API zum Auflisten der laufenden Prozesse?

Ich brauche eine C/C++ - API, mit der ich die laufenden Prozesse auf einem Linux-System auflisten und die Dateien auflisten kann, die für jeden Prozess geöffnet sind.

Ich möchte nicht möchte das Dateisystem/proc/direkt lesen.

Kann sich jemand einen Weg vorstellen, dies zu tun?

47
Thomi

http://procps.sourceforge.net/

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

Ist die Quelle von ps und anderen Prozesswerkzeugen. Sie verwenden tatsächlich proc (was darauf hindeutet, dass dies wahrscheinlich der konventionelle und beste Weg ist). Ihre Quelle ist gut lesbar. Die Datei

/procps-3.2.8/proc/readproc.c

Könnte nützlich sein. Ein nützlicher Vorschlag, da von ephemient gepostet wurde, ist die Verknüpfung mit der von libproc bereitgestellten API. Diese sollte in Ihrem Repo vorhanden sein (oder bereits installiert sein), aber Sie benötigen die "-dev" -Variante für die Header und was nicht.

Viel Glück

39
Aiden Bell

Wenn Sie nicht aus '/ proc lesen möchten. Dann können Sie ein Kernel-Modul schreiben, das Ihren eigenen Systemaufruf implementiert. Ihr Systemaufruf sollte so geschrieben sein, dass er die Liste der aktuellen Prozesse abrufen kann, z.

/* 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");
    }

Der obige Code ist meinem Artikel hier unter http://linuxgazette.net/133/saha.html zu entnehmen. Sobald Sie einen eigenen Systemaufruf haben, können Sie ihn aus Ihrem Benutzer-Space-Programm aufrufen.

23
user59634

Hier geht es (C/C++):

Sie hätten es hier finden können: http://ubuntuforums.org/showthread.php?t=657097

#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 ;
}
7
Stefan Steiger

Wenn Sie dies nicht tun, wird wahrscheinlich das verwendete/proc-Dateisystem gelesen. Hier einige Beispiele für ein Programm, das dies tut:

Aber leider stellt dies keine API dar.

7
shodanex

PS und jedes andere Werkzeug (EXCEPT für Kernel-Module) lesen aus /proc. /proc ist ein spezielles Dateisystem, das vom Kernel spontan erstellt wird, sodass Benutzermodusprozesse Daten lesen können, die sonst nur für den Kernel verfügbar sind. 

Der empfohlene Weg ist daher das Lesen von /proc.

Sie können das Dateisystem /proc schnell intuitiv betrachten, um zu sehen, wie es strukturiert ist . Für jeden Prozess gibt es einen /proc/pid, wobei pid die Prozess-ID-Nummer ist. In diesem Ordner befinden sich mehrere Dateien, die unterschiedliche Daten über den aktuellen Prozess enthalten. Wenn Sie ausführen

strace ps -aux

sie werden sehen, wie das Programm ps diese Daten aus /proc liest.

5
daniel

Es gibt eine Bibliothek libprocps aus dem procps-ng-Projekt . Wenn Sie unter Ubuntu 13.04 strace ps ausführen, sehen Sie, dass pslibprocps verwendet.

3
Craig McQueen

Die einzige Möglichkeit, dies ohne Lesen von/proc zu tun, wäre, "ps aux" aufzurufen, jede Zeile durchzugehen, die zweite Spalte (die PID) zu lesen und lsof -p [PID] damit aufzurufen.

... Ich würde vorschlagen,/proc zu lesen;)

3

Das Lesen von Proc ist nicht so schlecht. Ich kann Sie nicht in C++ zeigen, aber der folgende D-Code sollte Sie in die richtige Richtung weisen:

 import std.stdio; 
 import std.string; 
 import std.file; 
 import std.regexp; 
 import std.c.linux.linux; 
__. alias std.string.split explodiert; 

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

 Zeichenfolge [] scanPidDirs (Zeichenfolgeziel) 
 {
 string [] result; 

 bool callback (DirEntry * de) 
 {
 if (de.isdir) 
 {
 if (rex.find (de.name)> = 0) 
 {
 string [] a = explode (de.name, "/");
 Zeichenfolge pid = a [a.length-1]; 
 Zeichenfolge x = Besetzung (Zeichenfolge) std.file.read (de.name ~ "/status");
 int n = rext.find (x); 
 if (n> = 0) 
 {
 x = cast (string) std.file.read (de.name ~ "/cmdline");
 // Dies ist null beendet 
 wenn (x.Länge) x.Länge = x.Länge-1; 
 a = explodieren (x, "/");
 if (a.length) 
 x = a [a.Länge-1]; 
 sonst
 x = ""; 
 if (x == Ziel) 
 {
 result ~ = pid ~ "/" ~ x; 
 } 
 } 
 } 
 } 
 Rückgabe wahr; 
 } 

 listdir ("/ proc" & Rückruf); 
 return result.dup; 
 } 

 void main (string [] args) 
 {
 rex = new RegExp (srex); 
 rext = new RegExp (trex); 
 string [] a = scanPidDirs (args [1]); 
 if (! a.length) 
 {
 writefln ("nicht gefunden"); 
 Rückkehr;
 } 
 writefln ("% d übereinstimmende Prozesse", a.length); 
 foreach (s; a) 
 {
 string [] p = explodieren (s, "/");
 int pid = atoi (p [0]); 
 writef ("Stop% s (% d)?", s, pid); 
 Zeichenfolge r = readln (); 
 if (r == "Y\n" || r == "y\n") 
 kill (pid, SIGUSR1); 
 } 
} 
2
user253411

PID eines Prozesses nach Namen einfach suchen

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);
}
0
Md Muazzam