如何在 QNX cpp 代码中通过进程名称将 SIGTERM 发送到进程?
How to send SIGTERM to a process by process name in QNX cpp code?
例如:我有一个名为 foo 的进程。
通常在控制台中,我可以输入 slay foo
然后 foo 终止。
此外,在 cpp 代码中,我可以使用 system("slay foo");
发出系统调用
我知道 system() 是一个应该避免的繁重的 fork 调用。 <csignal>
或<cstdlib>
还有其他功能可以选择吗?
我读过 SignalKill() 和 SignalKill_r(),两者都需要我无法提供的 pid。
这并不像人们想象的那么简单。 Linux 没有提供一个 syscall
可以通过名称为您提供进程的 PID
。
假设 QNX
s 文件系统类似于标准 UNI,您可能需要阅读 this article 以了解如何使用其名称查找进程的 PID
,然后使用 PID
与 SignalKill
或 SignalKill_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] != '[=10=]'; 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;
}
为了将进程名称转换为 pid,您需要深入了解 QNX 的 /proc 文件系统。我写了一本名为 "The QNX Cookbook" 的书,现在可以在 QNX 的网站 (http://www.qnx.com/download/feature.html?programid=26184) 上免费在线获取。转到第 222 页,"Iterating through the list of processes" 并复制循环访问进程列表的代码。这将允许您在所有进程中搜索要杀死的进程(它将为您提供所需的 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()" 提供您想要的任何操作,您可以例如点名杀人等
例如:我有一个名为 foo 的进程。
通常在控制台中,我可以输入 slay foo
然后 foo 终止。
此外,在 cpp 代码中,我可以使用 system("slay foo");
我知道 system() 是一个应该避免的繁重的 fork 调用。 <csignal>
或<cstdlib>
还有其他功能可以选择吗?
我读过 SignalKill() 和 SignalKill_r(),两者都需要我无法提供的 pid。
这并不像人们想象的那么简单。 Linux 没有提供一个 syscall
可以通过名称为您提供进程的 PID
。
假设 QNX
s 文件系统类似于标准 UNI,您可能需要阅读 this article 以了解如何使用其名称查找进程的 PID
,然后使用 PID
与 SignalKill
或 SignalKill_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] != '[=10=]'; 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;
}
为了将进程名称转换为 pid,您需要深入了解 QNX 的 /proc 文件系统。我写了一本名为 "The QNX Cookbook" 的书,现在可以在 QNX 的网站 (http://www.qnx.com/download/feature.html?programid=26184) 上免费在线获取。转到第 222 页,"Iterating through the list of processes" 并复制循环访问进程列表的代码。这将允许您在所有进程中搜索要杀死的进程(它将为您提供所需的 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()" 提供您想要的任何操作,您可以例如点名杀人等