Linux API to list running processes? Linux API to list running processes? c c

Linux API to list running processes?


http://procps.sourceforge.net/

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

Is the source of ps and other process tools. They do indeed use proc (indicating it is probably the conventional and best way). Their source is quite readable. The file

/procps-3.2.8/proc/readproc.c

May be useful. Also a useful suggestion as posted by ephemient is linking to the API provided by libproc, which should be available in your repo (or already installed I would say) but you will need the "-dev" variation for the headers and what-not.

Good Luck


If you do not want to read from '/proc. Then you can consider writing a Kernel module which will implement your own system call. And your system call should be written so that it can obtain the list of current processes, such as:

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

The code above is taken from my article here at http://linuxgazette.net/133/saha.html.Once you have your own system call, you can call it from your user space program.


Here you go (C/C++):

You could have found it here:http://ubuntuforums.org/showthread.php?t=657097

Essentially, what it does is loop through all numeric folders in /proc/<pid>, and then it does a readlink on /proc/<pid>/exe, or if you want the command-line-arguments cat /proc/<pid>/cmdline

The file-descriptors open by the process are in /proc/<pid>/fd/<descriptor>, and you get the file name by doing a readlink on each symlink, e.g. readlink /proc/<pid>/fd/<descriptor>. fd can be a device, such as /dev/null, a socket, or a file, and potentially more.

#include <unistd.h>

ssize_t readlink(const char *path, char *buf, size_t bufsiz);
On success, readlink() returns the number of bytes placed in buf.
On error, -1 is returned and errno is set to indicate the error.

This is, by the way, the same that readproc.c does (or at least did).
Of course, hopefully they did it without buffer overflow possiblity.

#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     0int 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 __cpluspluspid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)#elsepid_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)#endifint main(){    pid_t pid = GetPIDbyName("bash") ; // If -1 = not found, if -2 = proc fs access error    printf("PID %d\n", pid);    return EXIT_SUCCESS ;}