. .

C: Prozessnamen einer PID unter Linux, HP-UX, MacOS und Solaris ermitteln


In diesem Beispiel zeige ich, wie unter Linux, HP-UX, MacOS und Solaris zu einer Prozess ID der Name des Prozesses ermittelt werden kann.
Wiederum die Definition der Funktionen im entsprechenden Header (processname.h):

#ifndef PRJ_PROCESSNAME_H
#define PRJ_PROCESSNAME_H 1

#define MAX_PROCNAME 1024

#ifdef __cplusplus
extern "C" {
#endif

int
prjProcessName(int pid, char *procname);

#ifdef __cplusplus
}
#endif

#endif /* !PRJ_PROCESSNAME */

Nach der überschaubaren Headerdatei nun der eigentliche Code in processname.c:
Dabei wird an Hand einer Definition entschieden, um welches System es sich handelt. Das sollte natürlich vom configure-Script bestimmt werden, hier in diesem Beispiel aber hartcodiert.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* #define DARWIN 1 */
/* #define HPUX 1 */
#define LINUX 1 /* should come from configure script or similar */
/* #define SOLARIS 1 */

#if defined(DARWIN)
#   include <libproc.h>

#elif defined(HPUX)
#   ifndef _INCLUDE_HPUX_SOURCE
#       define _INCLUDE_HPUX_SOURCE
#   endif
#   include <sys/pstat.h>
#   include <sys/pstat/pstat_ops.h>

#elif defined(SOLARIS)
#   include <procfs.h>
#   include <fcntl.h>

#endif

#include "processname.h"

/**
 * \brief   prjProcessName
 *
 * Ermittelt den Namen eines Prozesses,
 * implementiert fuer Linux, HP-UX, MacOS und Solaris.
 *
 * \param   pid         ProzessID des Prozesses, dessen Namen ermittelt werden soll.
 * \param   procname    Rueckgabe des Prozessnamens
 *
 * \return              Status-Code
 */
int
prjProcessName(int pid, char *procname) {

#if defined(DARWIN)
    struct proc_bsdshortinfo info;
    int retval;

    retval = proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof(info));
    if ((retval == sizeof(info)) && (*info.pbsi_comm != '\0')) {
        strncpy(procname, info.pbsi_comm, MAX_PROCNAME);
        return 0;
    }   

    return -1; 

#elif defined(HPUX)
    char long_command[MAX_PROCNAME];
    union pstun pu; 
 
    pu.pst_command = long_command;
    if (pstat(PSTAT_GETCOMMANDLINE, pu, MAX_PROCNAME, 1, pid) == -1) 
        return -1; 
 
    strncpy(procname, pu.pst_command, MAX_PROCNAME);
 
    return 0;
 
#elif defined(LINUX)
    FILE *quelle;
    char long_command[MAX_PROCNAME];
    char procfile[100];
 
    snprintf(procfile, (size_t) 100, "/proc/%d/cmdline", pid);
    if ((quelle = fopen(procfile, "r")) == NULL)
        return -1; 
 
    fgets(long_command, MAX_PROCNAME, quelle);
 
    strncpy(procname, long_command, (size_t) MAX_PROCNAME);
 
    fclose(quelle);
     
    return 0;
 
#elif defined(SOLARIS)
    psinfo_t psinfo;
    int fd; 
    char procfile[100];

    snprintf(procfile, (size_t) 100, "/proc/%d/psinfo", pid);

    if ((fd = open(procfile, O_RDONLY)) >= 0)
        if (read(fd, &psinfo, sizeof(psinfo_t)) != -1) {
            strncpy(procname, psinfo.pr_fname, (size_t) MAX_PROCNAME);
            return 0;
        }

    return -1;

#else /* not implemented yet */
    (void) pid;
    (void) procname;

    return -1;
#endif
}

Daraufhin kann der Prozessname einer Prozess ID zum Beispiel so ausgegeben werden:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

#include "processname.h"

/* ************************************************************************************ */

int
main(int argc, char *argv[]) {
    (void) argc; /* avoid compiler warnings */
    (void) argv;
 
    char procname[MAX_PROCNAME];
    int ownPid = (int) getpid();
 
    if (prjProcessName(ownPid, procname) == -1) {
        printf("\nError getting processname of pid `%d'.\n", ownPid);
    } else {
        printf("\nProcessname of pid `%d' is `%s'.\n", ownPid, procname);
    }
 
    return 0;
}

Kompiliert werden kann das Binary wie gewohnt zum Beispiel mit gcc.

gcc -Wall -Wextra -Werror -o get_processname processname.c get_processname.c

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>