I want to list all of the processes in the system. I used to use shell command "ps" and system function to get the result. However, it seems a little complex. How to use UNIX C functions to complete this job.
8 Answers
Under Linux you can examine the pseudo filesystem /proc for process information. That means using the opendir() set of functions and looking for sub-directories that are numbers - these are the process identifiers of each of the processes running on the system. There are numerous files within each sub-directory, that can be opened and read using open()/read() as long as your process has the required privileges.
See the
proc(5)
manpage for more details of the information available to you.
Comments
While you're definitely encouraged to browse the pseudo /proc filesystem, from a C/C++ program you should be using proc/readproc.h that is part of libprocps and is capable of accessing the same information.
E.g. on Debian based distribution you'll need to install libprocps-dev:
apt install libprocps-dev
You can list your processes this way, see man openproc for available flags:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <proc/readproc.h>
using std::cout;
int main()
{
PROCTAB* proc = openproc(PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS);
proc_t proc_info;
memset(&proc_info, 0, sizeof(proc_info));
cout << "Program\tPID\tPPID\tMEM\tutime\tstime\n";
while (readproc(proc, &proc_info) != NULL) {
cout << proc_info.cmd << "\t" << proc_info.tid;
cout << proc_info.ppid << "\t" << proc_info.resident;
cout << proc_info.utime << "\t" << proc_info.stime << "\n";
}
closeproc(proc);
return 0;
}
and compile it:
g++ -g -Wall -O2 readps.cc -o readps -lprocps
Comments
ps is the standard, for better or worse. It has many under-appreciated formatting options that can simplify your cross-platform parsing of its output.
/proc is more convenient, but not portable, and might be unavailable locally even where supported (e.g., in a chroot environment).
Comments
There is a finish solution for this.
See https://sourceforge.net/p/readproc/code/ci/master/tree/
clone it using git and do what you want.
#include"read_proc.h"
int main(void)
{
struct Root * root=read_proc();
struct Job * buffer;
int i=0;
for(;i<root->len;i++)
{
buffer=get_from_place(root,i);
printf("%s\t%u\n",buffer->name,buffer->pid);
}
return 0;
}
2 Comments
There are no standards for finding process information; each Unix vendor gets to provide their own mechanism for providing information to system administrators.
Linux and Solaris use the /proc/ filesystem to export information on processes to userspace, but I do not think they are at all compatible. (I have a vague recollection that Solaris decided to export all its information in a binary format to remove in-kernel processing, at the expense of more closely tying userspace programs to kernel datastructures. The top program used to be very good at peeking into kernel memory to read process tables, I'm not sure it needs to any more, but maybe all the historical knowledge is still baked in.)
If you want to be platform-specific, the Linux proc(5) manpage has the information you need. Happy hacking. :)
1 Comment
You just need to list /proc/ directory =) My question may be somewhat helpful for you.
4 Comments
#assume target running /root/eclipse_android/targetname/targetname usb 1 2 3
#here list all process and get args
#
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
static int is_Pid_Dir(const struct dirent* entry)
{
const char* p;
for (p = entry->d_name; *p; p++)
{
if (!isdigit(*p))
return false;
}
return true;
}
static void List_Command()
{
char szProc[256];
char szFullLine[256];
char szCmd[256];
char szType[64];
int iLocationId;
int iAction;
int iCount;
int iHit;
size_t stCmdLen;
char* szName;
FILE* fp;
DIR* dProcPath;
struct dirent* entry;
// Open /proc directory.
dProcPath = opendir("/proc");
if (dProcPath)
{
// Iterate through all files and directories of /proc.
while ((entry = readdir(dProcPath)))
{
// Skip anything that is not a PID directory.
if (is_Pid_Dir(entry))
{
//if want all status open /proc/<PID>/status
//if want get cmdline open /proc/<PID>/cmdline
snprintf(szProc, sizeof(szProc), "/proc/%s/cmdline", entry->d_name);
fp = fopen(szProc, "r");
if (fp)
{
// Get PID, process name and number of faults.
//fscanf(fp, "%s %s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %lu", &pid, &szProc, &maj_faults);
memset(szFullLine, 0x00, sizeof(szFullLine));
stCmdLen = fread(szFullLine, sizeof(char), sizeof(szFullLine), fp);
fclose(fp);
if( stCmdLen > 0 )
{
szName = strstr(szFullLine, "targetname");
if( szName )
{
iHit = 0;
for(iCount=0; iCount<stCmdLen-1; iCount++)
{
if( szFullLine[iCount] == '\x00' )
{
iHit++;
szFullLine[iCount] = ' ';
}
}
//sscanf("19 cool kid", "%d %[^\n]", &iCount, szType);
if( iHit >= 3 )
{
sscanf(szFullLine, "%[^' '] %[^' '] %d %d", szCmd, szType, &iLocationId, &iAction);
printf("%s %s %d %d\n", szCmd, szType, iLocationId, iAction);
}
}
}
}
}
}
}
closedir(dProcPath);
}
also cpp: https://cplusplus.com/forum/unices/221977/
download https://busybox.net/downloads/
extract and trace ps.c, procps.c full api procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)