Reputation: 1028
E.g: I have a process called foo.
Typically in console, I can type slay foo
then foo terminates.
Also, in a cpp code I can issue a system call with system("slay foo");
I know the system() is a heavy fork call that should be avoid. Is there any other function in <csignal>
or <cstdlib>
I can choose?
I've read SignalKill() and SignalKill_r(), both need pid which I cannot provide.
Upvotes: 1
Views: 2532
Reputation: 5550
It's not as simple as one might think. Linux doesn't provide a syscall
that gives you the PID
of a process by its name.
Assuming QNX
s filesystem is similar to standard UNI, you might want to read this article to understand how to find a process's PID
using its name, and then use that PID
with SignalKill
or SignalKill_r
Here's the code to find a process's PID
using its name in C. I can't test it on QNX
, but it works on 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;
}
Upvotes: 2
Reputation: 57
In order to convert a process name to a pid, you need to dig through QNX's /proc filesystem. I wrote a book called "The QNX Cookbook" which is now available for free online at QNX's website (http://www.qnx.com/download/feature.html?programid=26184). Go to page 222, "Iterating through the list of processes" and copy the code that iterates through the list of processes. This will allow you to search through all processes for whichever ones you want to kill (it will give you the PID you need).
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);
}
By supplying whatever actions you want for "do_process()", you can e.g. kill by name, etc.
Upvotes: 1