2015-05-28 21 views
1

例如:我有一个叫做foo的进程。如何通过QNX cpp代码中的进程名称向进程发送SIGTERM?

通常在控制台中,我可以键入slay foo然后foo终止。 此外,在一个cpp代码我可以发出一个系统调用system("slay foo");

我知道系统()是一个沉重的应该避免的分叉调用。我可以选择<csignal>还是<cstdlib>还有其他功能吗?

我读过SignalKill()和SignalKill_r(),都需要pid,我不能提供。

+0

busybox源代码显示你如何做到这一点,或者你可能只需链接libbb –

回答

1

这并不像人们想象的那么简单。 Linux不提供syscall,通过名称为您提供进程的PID

假设QNX小号的文件系统是类似于标准UNI,你可能需要阅读this article,以了解进程的PID使用其名称查找,然后使用PIDSignalKillSignalKill_r

下面的代码找到在C中使用其名称的进程的PID。我无法在QNX上进行测试,但它可以在Ubuntu上运行。

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <dirent.h> 
#include <libgen.h> 

/* checks if the string is purely an integer 
* we can do it with `strtol' also 
*/ 
int check_if_number (char *str) 
{ 
    int i; 
    for (i=0; str[i] != '\0'; i++) 
    { 
    if (!isdigit (str[i])) 
    { 
     return 0; 
    } 
    } 
    return 1; 
} 

#define MAX_BUF 1024 
#define PID_LIST_BLOCK 32 

int *pidof (char *pname) 
{ 
    DIR *dirp; 
    FILE *fp; 
    struct dirent *entry; 
    int *pidlist, pidlist_index = 0, pidlist_realloc_count = 1; 
    char path[MAX_BUF], read_buf[MAX_BUF]; 

    dirp = opendir ("/proc/"); 
    if (dirp == NULL) 
    { 
    perror ("Fail"); 
    return NULL; 
    } 

    pidlist = malloc (sizeof (int) * PID_LIST_BLOCK); 
    if (pidlist == NULL) 
    { 
    return NULL; 
    } 

    while ((entry = readdir (dirp)) != NULL) 
    { 
    if (check_if_number (entry->d_name)) 
    { 
     strcpy (path, "/proc/"); 
     strcat (path, entry->d_name); 
     strcat (path, "/comm"); 

     /* A file may not exist, it may have been removed. 
     * dut to termination of the process. Actually we need to 
     * make sure the error is actually file does not exist to 
     * be accurate. 
     */ 
     fp = fopen (path, "r"); 
     if (fp != NULL) 
     { 
     fscanf (fp, "%s", read_buf); 
     if (strcmp (read_buf, pname) == 0) 
     { 
      /* add to list and expand list if needed */ 
      pidlist[pidlist_index++] = atoi (entry->d_name); 
      if (pidlist_index == PID_LIST_BLOCK * pidlist_realloc_count) 
      { 
      pidlist_realloc_count++; 
      pidlist = realloc (pidlist, sizeof (int) * PID_LIST_BLOCK * pidlist_realloc_count); //Error check todo 
      if (pidlist == NULL) 
      { 
       return NULL; 
      } 
      } 
     } 
     fclose (fp); 
     } 
    } 
    } 


    closedir (dirp); 
    pidlist[pidlist_index] = -1; /* indicates end of list */ 
    return pidlist; 
} 

int main (int argc, char *argv[]) 
{ 
    int *list, i; 

    if (argc != 2) 
    { 
    printf ("Usage: %s proc_name\n", argv[0]); 
    return 0; 
    } 
    list = pidof (argv[1]); 
    for (i=0; list[i] != -1; i++) 
    { 
    printf ("%d ", list[i]); 
    } 
    free (list); 
    if (list[0] != -1) 
    { 
    printf ("\n"); 
    } 
    return 0; 
} 
+0

如果需要这么多的工作(打开目录和文件等),那么你可能只是使用*系统(“slay foo”)* – ooga

+0

@ooga谁说'slay'更有效率?我不知道任何'qnx' API使其更快 –

+0

谢谢,它工作得很好!我想知道为什么QNX不提供系统调用来返回这样的事情。 – BigTailWolf

0

为了一个过程名转换为PID,你需要通过QNX的/ proc文件系统来挖。我写了一本名为“The QNX Cookbook”的书,现在可以在QNX的网站(http://www.qnx.com/download/feature.html?programid=26184)上免费在线阅读。转到第222页,“遍历进程列表”并复制遍历进程列表的代码。这将允许你搜索所有你想杀的进程(它会给你你需要的PID)。

void 
iterate_processes (void) 
{ 
    struct dirent *dirent; 
    DIR    *dir; 
    int    r; 
    int    pid; 

    // 1) find all processes 
    if (!(dir = opendir ("/proc"))) { 
    fprintf (stderr, "%s: couldn't open /proc, errno %d\n", 
      progname, errno); 
    perror (NULL); 
    exit (EXIT_FAILURE); 
    } 

    while (dirent = readdir (dir)) { 
    // 2) we are only interested in process IDs 
    if (isdigit (*dirent -> d_name)) { 
     pid = atoi (dirent -> d_name); 
     iterate_process (pid); 
    } 
    } 
    closedir (dir); 
} 

void 
iterate_process (int pid) 
{ 
    char  paths [PATH_MAX]; 
    int  fd; 

    // 1) set up structure 
    static struct { 
    procfs_debuginfo info; 
    char    buff [PATH_MAX]; 
    } name; 

    sprintf (paths, "/proc/%d/as", pid); 

    if ((fd = open (paths, O_RDONLY)) == -1) { 
    return; 
    } 

    // 2) ask for the name 
    if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, &name, 
       sizeof (name), 0) != EOK) { 
    if (pid == 1) { 
     strcpy (name.info.path, "(procnto)"); 
    } else { 
     strcpy (name.info.path, "(n/a)"); 
    } 
    } 

    // 3) we can compare against name.info.path here... 
    do_process (pid, fd, name.info.path); 
    close (fd); 
} 

通过为“do_process()”提供您想要的任何动作,您可以杀死名称等