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; }