web-dev-qa-db-ja.com

実行中のプロセスをリストするLinux API?

Linuxシステムで実行中のプロセスを一覧表示し、各プロセスが開いているファイルを一覧表示できるC/C++ APIが必要です。

not最終的に/ proc /ファイルシステムを直接読みたい。

誰もこれを行う方法を考えることができますか?

48
Thomi

http://procps.sourceforge.net/

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

Psおよびその他のプロセスツールのソースです。彼らは確かにprocを使用します(おそらく従来の最善の方法であることを示しています)。そのソースは非常に読みやすいです。ファイル

/procps-3.2.8/proc/readproc.c

役に立つかもしれません。また、ephemientによる投稿として役立つ提案は、libprocによって提供されるAPIへのリンクです。ヘッダーとwhat-notの「-dev」バリエーション。

幸運

40
Aiden Bell

'/ procから読みたくない場合。次に、独自のシステムコールを実装するカーネルモジュールの作成を検討できます。また、次のような現在のプロセスのリストを取得できるように、システムコールを記述する必要があります。

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

上記のコードは http://linuxgazette.net/133/saha.html にある私の記事から引用したものです。独自のシステムコールを作成したら、ユーザースペースプログラムから呼び出すことができます。

23
user59634

そうしないと、使用するどんなAPIでも/ procファイルシステムを読み取ることになります。これを行うプログラムの例を次に示します。

しかし、残念ながら、それはAPIを構成するものではありません。

8
shodanex

どうぞ(C/C++):

ここで見つけることができました: http://ubuntuforums.org/showthread.php?t=657097

基本的に、/proc/<pid>のすべての数値フォルダーをループし、/proc/<pid>/exeでreadlinkを実行するか、コマンドライン引数cat /proc/<pid>/cmdlineが必要な場合

ちなみに、これはreadproc.cが行うのと同じです(または少なくともやった)。
もちろん、うまくいけば、バッファオーバーフローの可能性なしにそれを実行できます。

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

PSおよびその他すべてのツール(カーネルモジュールを除く)は、/procから読み取ります。 /procは、カーネルによってオンザフライで作成される特別なファイルシステムです。これにより、ユーザーモードプロセスは、他の方法ではカーネルでのみ利用可能なデータを読み取ることができます。

したがって、推奨される方法は、/procから読み取ることです。

/procファイルシステムをすばやく直感的に見て、その構造を確認できます。すべてのプロセスには/proc/pidがあり、pidはプロセスID番号です。このフォルダ内には、現在のプロセスに関する異なるデータを含むいくつかのファイルがあります。走ったら

strace ps -aux

プログラムps/procからこのデータを読み取る方法がわかります。

5
daniel

procps-ngプロジェクト のライブラリlibprocpsがあります。 Ubuntu 13.04では、strace psを実行すると、pslibprocpsを使用していることがわかります。

3
Craig McQueen

/ procを読み取らずにこれを行う唯一の方法は、「ps aux」を呼び出し、すべての行を調べ、2番目の列(PID)を読み取り、lsof -p [PID]を呼び出します。

.../procを読むことをお勧めします;)

3

Procの読み取りはそれほど悪くはありません。 C++では表示できませんが、次のDコードは正しい方向を示しています。

 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");
 //このiヌル終了
 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); 
 foリーチ(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
user253411