Killall
-- Sebastian Pawlak, 2005.
Przedstawione funkcje umożliwiają odnalezienie w systemie Linux PIDów procesów powiązanych z programem o zadanej nazwie. Zaimplementowane zostały także funkcje umożliwiające wysłanie sygnałów do procesów powiązanych z programem o zadanej nazwie.
Kod źródłowy pliku "kill.h":
/* kill.h: library of functions which allow to kill processes of known names;
* it serves processes compressed with UPX or uncompressed run
* by different processes
*
* Sebastian Pawlak, 2005.
*/
#ifndef _KILL_H_
#define _KILL_H_
enum {
MAX_PRG = 10, /* max. programs */
MAX_PIDS = 8, /* max. PIDs for one name of a program */
MAX_VAL = 64 /* max. length of program's name */
};
int name2pid(const char *name, pid_t *pid);
void killPrograms(const char name[][MAX_VAL + 1], int signo);
void killProgram(const char *name, int signo);
#endif
Kod źródłowy pliku "kill.c":
/* kill.c: library of functions which allow to kill processes of known names;
* it serves processes compressed with UPX or uncompressed run
* by different processes
*
* Sebastian Pawlak, 2005.
*/
#include <stdio.h>
#include <stdlib.h> /* for strtol() */
#include <unistd.h> /* for usleep() */
#include <sys/types.h> /* for pid_t */
#include <dirent.h> /* for opendir(), readdir() */
#include <signal.h>
#include "kill.h"
#define DEBUG
/* name2pid: finds PIDs of processes of a program with known name;
* returns -1, in case of an error or not found a process;
* returns positive value, which stays for number of found PIDs;
* found PIDs are written in pids[];
* looking for processes is done with use of:
* file /proc/XXXX/cmdline and link /proc/XXXX/exe
*/
int name2pid(const char *name, pid_t pids[])
{
DIR *dir = NULL;
struct dirent *dire = NULL;
FILE *f = NULL;
char s[256], linkName[64 + 1];
pid_t pidTmp;
int i = 0, n, isFound;
/* opens "directory stream" -- a pointer points to a first element in
* opened directory
*/
if ((dir = opendir("/proc")) == NULL) {
fprintf(stderr, "Problem with opendir()!");
return -1;
}
/* looks in subdirectories in a directory /proc */
while ((dire = readdir(dir)) != NULL) {
/* if a name of a subdirectory /proc/XXXX is a number */
if ((pidTmp = strtol(dire->d_name, NULL, 10)) > 0) {
isFound = 0;
/* if a link /proc/XXXX/exe contains the name of running program,
* directory XXXX is the number of PID of process
*/
sprintf(s, "/proc/%s/exe", dire->d_name);
/* reads a name of a program pointed by a link "exe" */
if ((n = readlink(s, linkName, 64)) != -1) {
linkName[n] = '\0';
/* if a link points to a file agreed with "name",
* we found seeking PID
*/
if ((strstr(linkName, name) != NULL) && (i < MAX_PIDS)) {
pids[i] = pidTmp;
i++;
isFound = 1;
}
}
if (isFound == 0) {
/* if a file /proc/XXXX/cmdline contains a name of run program,
* a directory XXXX is a number which stays for PID of process
*/
sprintf(s, "/proc/%s/cmdline", dire->d_name);
if ((f = fopen(s, "r")) != NULL) {
if (fgets(s, 255, f) != NULL) {
/* if in a file "cmdline" is text agreed with "name",
* we found seeking PID
*/
if ((strstr(s, name) != NULL) && (i < MAX_PIDS)) {
pids[i] = pidTmp;
i++;
}
}
fclose(f);
}
}
}
}
closedir(dir);
if (i == 0)
return -1;
return i;
}
/* killPrograms: kills all processes connected with supplied names of programs
*/
void killPrograms(const char name[][MAX_VAL + 1], int signo)
{
pid_t pids[MAX_PIDS];
int i, k;
/* kills a following program */
for (i = 0; i < MAX_PRG; i++) {
if (name[i][0] == '\0')
continue;
/* converts a name of program to PIDs */
if ((k = name2pid(name[i], pids)) != -1) {
/* kills following PIDs for the same name of a program */
for (--k; k >= 0; k--) {
if (kill(pids[k], signo) == -1)
fprintf(stderr, "Problem with kill()!");
else {
#ifdef DEBUG
fprintf(stdout, "Killed a process no.: %d.\n", pids[k]);
#endif
}
}
}
}
}
/* killProgram: kills all processes connected with supplied name of a program
*/
void killProgram(const char *name, int signo)
{
pid_t pids[MAX_PIDS];
int k;
/* converts a name of a program to PIDs */
if ((k = name2pid(name, pids)) != -1) {
/* kills following PIDs for the same name of a program */
for (--k; k >= 0; k--) {
if (kill(pids[k], signo) == -1)
fprintf(stderr, "Problem with kill()!");
else {
#ifdef DEBUG
fprintf(stdout, "Killed a process no.: %d.\n", pids[k]);
#endif
}
}
}
}
Kod źródłowy pliku "main.c":
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include "kill.h"
#define PROG_NAME "bash"
int main(void)
{
const char names[MAX_PRG][MAX_VAL + 1] = { "xterm", "xcalc" };
pid_t pids[MAX_PIDS] = { 0 };
int pidsCntr = 0;
int i;
pidsCntr = name2pid(PROG_NAME, pids);
if (pidsCntr == -1)
return -1;
/* Listing processes which are connected with a program PROG_NAME */
fprintf(stdout, "PIDs of processes of program \""PROG_NAME"\":\n");
for (i = 0; i < pidsCntr; i++)
fprintf(stdout, "pid %d: %d\n", i, pids[i]);
/* Killing processes which names are stored in "names" */
killPrograms((const char (*)[])names, SIGKILL);
return 0;
}





