Linux API to display running processes?

I need a C / C ++ API that allows me to list running processes on a Linux system and list the files opened by each process.

I do not want to read the / proc / file system directly.

Can anyone think of a way to do this?

+49
c ++ c linux api process
Jun 02 '09 at 14:06
source share
10 answers

http://procps.sourceforge.net/

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

It is the source of ps and other process tools. They really use proc (indicating that this is probably the usual and best way). Their source is quite readable. File

/procps-3.2.8/proc/readproc.c 

May be helpful. Also a useful suggestion, like that sent by ephemient , refers 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 option for headers and no.

Luck

+41
Jun 02 '09 at 14:22
source share

If you do not want to read from '/ proc. You can then consider creating a Kernel module that will implement your own system call. And your system call should be written so that it can get a list of current processes, for example:

 /* 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 . When you have your system call, you can call him from your user space program.

+24
Jun 02 '09 at 16:25
source share

If you do not, I think that any API that you use will end reading the / proc file system. Here are some examples of how to run this program:

But, unfortunately, this is not an API.

+8
Jun 02 '09 at 14:35
source share

Here you are (C / C ++):

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

Essentially, it loops through all the numerical folders in /proc/<pid> and then executes a read link in /proc/<pid>/exe or, if you need cat /proc/<pid>/cmdline command line arguments

By the way, this is the same as readproc.c does (or at least did).
Of course, we hope that they did this without the possibility of a buffer overflow.

 #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 ; } 
+8
Sep 26 '10 at 11:42 on
source share

PS and any other tool (EXCEPT for kernel modules) starting with /proc . /proc is a special file system created on the fly by the kernel, so user-mode processes can read data that would otherwise be available only to the kernel.

Therefore, the recommended way is to read from /proc .

You can quickly and intuitively look at the /proc file system to see how it is structured. For each process, there is /proc/pid , where pid is the process identifier number. Inside this folder there are several files that contain different data about the current process. If you run

 strace ps -aux 

you will see how ps reads this data from /proc .

+5
Jun 02 '09 at 19:00
source share

The only way to do this without reading / proc is to call "ps aux", go through each row, read the second column (PID) and call lsof -p [PID] with it.

... I would suggest reading / proc;)

+4
Jun 02 '09 at 14:50
source share

There is the libprocps library from the procps-ng project. In Ubuntu 13.04, if you are running strace ps , you can see that ps uses libprocps .

+3
Aug 26 '13 at 5:01
source share

Reading proc is not so bad. I can't show you in C ++, but the following D code should point you in the right direction:

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

 alias std.string.split explode;

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

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

       bool callback (DirEntry * de)
       {
          if (de.isdir)
          {
             if (rex.find (de.name)> = 0)
             {
                 string [] a = explode (de.name, "/");
                 string 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");
                     // This is null terminated
                     if (x.length) x.length = x.length-1;
                     a = explode (x, "/");
                     if (a.length)
                        x = a [a.length-1];
                     else
                        x = "";
                      if (x == target)
                     {
                         result ~ = pid ~ "/" ~ x;
                     }
                 }
              }
           }
           return true;
       }

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

 void main (string [] args)
 {
     rex = new RegExp (srex);
     rext = new RegExp (trex);
     string [] a = scanPidDirs (args [1]);
     if (! a.length)
     {
         writefln ("Not found");
         return
     }
     writefln ("% d matching processes", a.length);
     foreach (s; a)
     {
        string [] p = explode (s, "/");
        int pid = atoi (p [0]);
        writef ("Stop% s (% d)?", s, pid);
        string r = readln ();
        if (r == "Y \ n" || r == "y \ n")
           kill (pid, SIGUSR1);
     }
 }
+2
Jan 18
source share

An easy way to schedule the pid of any process named

 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
Sep 07 '17 at 6:31 on
source share
 #include <stdio.h> #include <stdlib.h> #include <string.h> char *mystrstr(const char *haystack,const char *needle); main() { char *str1="abc dc abcd abce"; char *str2="ab"; char *ptr=NULL; int cnt=0; int offset=0; while(*str1) { ptr=mystrstr(str1,str2); if(ptr==NULL) break; cnt++; offset=ptr-str1+strlen(str2); str1=str1+offset; } printf("Num of substr [%s] = %d\n",str2,cnt ); } char *mystrstr(const char *haystack,const char *needle) { int i=0,j=1; for(;haystack[i];i++) { if(needle[0]==haystack[i]) { for(;needle[j];j++) { if(needle[j]==haystack[i+j] ) { if(needle[j]!='\0') continue; } else break; } if(needle[j]=='\0') return haystack + i; else if(haystack[i]!='\0') continue; } if(haystack[i]=='\0') return NULL; } } 
0
Nov 07 '17 at 11:33
source share



All Articles