J'ai besoin d'une API C/C++ qui me permet de répertorier les processus en cours sur un système Linux et de répertorier les fichiers ouverts par chaque processus.
Je ne pas veux finir par lire directement le système/proc/file.
Quelqu'un peut-il penser à un moyen de faire cela?
http://procps.sourceforge.net/
http://procps.cvs.sourceforge.net/viewvc/procps/procps/proc/readproc.c?view=markup
Est la source de ps et autres outils de processus. Ils utilisent en effet proc (indiquant que c'est probablement le moyen conventionnel et le meilleur). Leur source est assez lisible. Le fichier
/procps-3.2.8/proc/readproc.c
Peut être utile. Aussi, une suggestion utile comme posted by ephemient est un lien vers l'API fournie par libproc, qui devrait être disponible dans votre référentiel (ou déjà installée, je dirais) mais vous aurez besoin de la variante "-dev" pour les en-têtes et quoi-pas.
Bonne chance
Si vous ne voulez pas lire dans '/ proc. Ensuite, vous pouvez envisager d’écrire un module de noyau qui implémentera votre propre appel système. Et votre appel système doit être écrit pour pouvoir obtenir la liste des processus en cours, tels que:
/* 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");
}
Le code ci-dessus est tiré de mon article ici à l'adresse http://linuxgazette.net/133/saha.html . Une fois que vous avez votre propre appel système, vous pouvez l'appeler à partir de votre programme d'espace utilisateur.
Ici vous allez (C/C++):
Vous pourriez l'avoir trouvé ici: http://ubuntuforums.org/showthread.php?t=657097
#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 ;
}
PS et tous les autres outils (SAUF pour les modules de noyau) sont lus à partir de /proc
. /proc
est un système de fichiers spécial créé à la volée par le noyau afin que les processus en mode utilisateur puissent lire des données qui ne seraient autrement disponibles que pour le noyau.
La manière recommandée est donc de lire à partir de /proc
.
Vous pouvez rapidement et intuitivement examiner le système de fichiers /proc
pour voir comment il se structure . Pour chaque processus, il existe un /proc/pid
où pid est le numéro d'identification du processus. Dans ce dossier, vous trouverez plusieurs fichiers contenant différentes données sur le processus en cours.
strace ps -aux
vous verrez comment le programme ps
lit ces données à partir de /proc
.
Il existe une bibliothèque libprocps
à partir du projet procps-ng
. Sur Ubuntu 13.04, si vous utilisez strace ps
, alors vous pouvez voir que ps
utilise libprocps
.
La seule façon de le faire sans lire/proc serait d'appeler "ps aux", de parcourir toutes les lignes, de lire la deuxième colonne (le PID) et d'appeler lsof -p [PID] avec.
... Je suggère de lire/proc;)
Lire proc n'est pas trop mauvais. Je ne peux pas vous montrer en C++, mais le code D suivant devrait vous orienter dans la bonne 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 = "État: [\ t] [SR]" ; RegExp rex; RegExp rext; string [] scanPidDirs (string target) { string [] resultat; rappel de bool (DirEntry * de) { if (de.isdir) { if (rex.find (de.name)> = 0) { string [] a = explode (de.name, "/"); string pid = a [longueur.a1]; string x = cast (string) std.file.read (de.name ~ "/status"); int n = rext.find (x); si (n> = 0) { x = cast (chaîne) std.file.read (de.name ~ "/cmdline"); // Ceci est null terminé si (x.length) x.length = x.length-1; a = exploser (x, "/"); si (une.longueur) x = a [longueur.a1]; autre x = ""; si (x == cible) { résultat ~ = pid ~ "/" ~ x; } } } } retourne vrai; } listdir ("/ proc", & callback); return result.dup; } void main (string [] args) { rex = new RegExp (srex); rext = new RegExp (trex); string [] a = scanPidDirs (args [1]); si (! a.length) { writefln ("Introuvable"); revenir; } writefln ("% d processus correspondants", a.length); foreach (s; a) { string [] p = exploser (s, "/"); int pid = atoi (p [0]); writef ("Stop% s (% d)?", s, pid); chaîne r = readln (); if (r == "Y\n" || r == "y\n") tuer (pid, SIGUSR1); } }
Un moyen facile de trouver le pid de tout processus par son nom
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);
}