GNU/Linux >> Linux Esercitazione >  >> Linux

API Linux per elencare i processi in esecuzione?

http://procps.sourceforge.net/

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

È la fonte di ps e altri strumenti di processo. In effetti usano proc (indicando che è probabilmente il modo convenzionale e migliore). La loro fonte è abbastanza leggibile. Il file

/procps-3.2.8/proc/readproc.c

Può essere utile. Anche un suggerimento utile come pubblicato da ephemient si collega all'API fornita da libproc , che dovrebbe essere disponibile nel tuo repository (o già installato direi) ma avrai bisogno della variazione "-dev" per le intestazioni e quant'altro.

Buona fortuna


Se non vuoi leggere da '/proc. Quindi puoi considerare di scrivere un modulo del kernel che implementerà la tua chiamata di sistema. E la tua chiamata di sistema dovrebbe essere scritta in modo che possa ottenere l'elenco dei processi correnti, come:

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

Il codice sopra è tratto dal mio articolo qui su http://linuxgazette.net/133/saha.html. Una volta che hai la tua chiamata di sistema, puoi chiamarla dal tuo programma in spazio utente.


Ecco qua (C/C++):

Potresti averlo trovato qui:http://ubuntuforums.org/showthread.php?t=657097

Essenzialmente, quello che fa è scorrere tutte le cartelle numeriche in /proc/<pid> , e quindi esegue un readlink su /proc/<pid>/exe , o se vuoi gli argomenti della riga di comando cat /proc/<pid>/cmdline

I descrittori di file aperti dal processo sono in /proc/<pid>/fd/<descriptor> , e ottieni il nome del file facendo un readlink su ogni link simbolico, ad es. readlink /proc/<pid>/fd/<descriptor> . fd può essere un dispositivo, come /dev/null, un socket o un file e potenzialmente altro ancora.

#include

ssize_t readlink(const char *path, char *buf, size_t bufsiz);
In caso di successo, readlink() restituisce il numero di byte inseriti in buf.
In caso di errore, viene restituito -1 e viene impostato errno per indicare l'errore.

Questo è, tra l'altro, lo stesso di readproc.c fa (o almeno ha fatto).
Ovviamente, si spera che lo abbiano fatto senza possibilità di overflow del buffer.

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

Se non lo fai, suppongo che qualsiasi API utilizzerai finirà per leggere il filesystem /proc. Ecco alcuni esempi di programmi che eseguono questa operazione:

  • qps
  • htop
  • procps

Ma sfortunatamente, ciò non costituisce un'API.


Linux
  1. Come impostare i limiti sui processi di esecuzione degli utenti in Linux

  2. 3 modi per elencare gli utenti in Linux

  3. Come eliminare i processi in esecuzione in Linux

  4. comando Linux ps

  5. Comando Linux ls - Elenca file

Come trovare e uccidere i processi in esecuzione in Linux

Comando SS in Linux

Monitoraggio dei processi su Linux

Processi in esecuzione

Comprensione dei processi su Linux

Come trovare i migliori processi in esecuzione in base all'utilizzo di memoria e CPU in Linux