GNU/Linux >> Tutoriales Linux >  >> Linux

¿API de Linux para enumerar los procesos en ejecución?

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 probablemente sea la mejor y más convencional). Su fuente es bastante legible. El archivo

/procps-3.2.8/proc/readproc.c

Puede ser útil. También una sugerencia útil como publicada por ephemient se vincula a la API proporcionada por libproc , que debería estar disponible en su repositorio (o ya instalado, diría) pero necesitará la variación "-dev" para los encabezados y demás.

Buena suerte


Si no desea leer desde '/proc. Entonces 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 llamarla desde su programa de espacio de usuario.


Aquí tienes (C/C++):

Podrías haberlo encontrado aquí:http://ubuntuforums.org/showthread.php?t=657097

Esencialmente, lo que hace es recorrer todas las carpetas numéricas en /proc/<pid> , y luego hace un enlace de lectura en /proc/<pid>/exe , o si desea los argumentos de la línea de comandos cat /proc/<pid>/cmdline

Los descriptores de archivo abiertos por el proceso están en /proc/<pid>/fd/<descriptor> , y obtiene el nombre del archivo haciendo un enlace de lectura en cada enlace simbólico, p. readlink /proc/<pid>/fd/<descriptor> . fd puede ser un dispositivo, como /dev/null, un socket o un archivo, y potencialmente más.

#include

ssize_t readlink(const char *ruta, char *buf, size_t bufsiz);
En caso de éxito, readlink() devuelve el número de bytes colocados en buf.
En caso de error, se devuelve -1 y se establece errno para indicar el error.

Esto es, por cierto, lo mismo que readproc.c lo hace (o al menos lo hizo).
Por supuesto, con suerte lo hicieron sin la posibilidad de desbordamiento de búfer.

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

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

  • qps
  • arriba
  • procps

Pero desafortunadamente, eso no constituye una API.


Linux
  1. Cómo establecer límites en los procesos que ejecutan los usuarios en Linux

  2. 3 formas de listar usuarios en Linux

  3. Cómo matar procesos en ejecución en Linux

  4. ¿Cómo mostrar la lista de procesos en ejecución de Python?

  5. ¿Cuáles son estos procesos de Windows en Linux?

Cómo encontrar y matar procesos en ejecución en Linux

Comando SS en Linux

Supervisión de procesos en Linux

Procesos corriendo

Comprender los procesos en Linux

Cómo encontrar los principales procesos en ejecución por memoria y uso de CPU en Linux