home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / A / PS / PROCPS-0.000 / PROCPS-0 / procps-0.97 / killall.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-16  |  3.6 KB  |  145 lines

  1. /* killall.c  -  kill processes by name. Written by Werner Almesberger */
  2.  
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include <dirent.h>
  8. #include <signal.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <linux/sched.h>
  13. #include "signals.h"
  14.  
  15.  
  16. #define COMM_LEN  sizeof(dummy.comm)
  17. #define PROC_BASE "/proc"
  18. #define MAX_NAMES (sizeof(unsigned long)*8)
  19.  
  20.  
  21. static struct task_struct dummy;
  22. static int verbose = 0,interactive = 0;
  23.  
  24.  
  25. static int ask(char *name,pid_t pid)
  26. {
  27.     int ch,c;
  28.  
  29.     do {
  30.         printf("Kill %s(%d) ? (y/n) ",name,pid);
  31.         fflush(stdout);
  32.     do if ((ch = getchar()) == EOF) exit(0);
  33.     while (ch == '\n' || ch == '\t' || ch == ' ');
  34.     do if ((c = getchar()) == EOF) exit(0);
  35.     while (c != '\n');
  36.     }
  37.     while (ch != 'y' && ch != 'n' && ch != 'Y' && ch != 'N');
  38.     return ch == 'y' || ch == 'Y';
  39. }
  40.  
  41.  
  42. static int kill_all(int signal,int names,char **namelist)
  43. {
  44.     DIR *dir;
  45.     struct dirent *de;
  46.     FILE *file;
  47.     struct stat st,sts[MAX_NAMES];
  48.     char path[PATH_MAX+1],comm[COMM_LEN+1];
  49.     pid_t pid,self;
  50.     int empty,dummy,i;
  51.     unsigned long found;
  52.  
  53.     for (i = 0; i < names; i++)
  54.     if (!strchr(namelist[i],'/')) sts[i].st_dev = 0;
  55.     else if (stat(namelist[i],&sts[i]) < 0) {
  56.         perror(namelist[i]);
  57.         exit(1);
  58.         }
  59.     self = getpid();
  60.     found = 0;
  61.     if (!(dir = opendir(PROC_BASE))) {
  62.     perror(PROC_BASE);
  63.     exit(1);
  64.     }
  65.     empty = 1;
  66.     while (de = readdir(dir))
  67.     if ((pid = atoi(de->d_name)) && pid != self) {
  68.         sprintf(path,"%s/%d/stat",PROC_BASE,pid);
  69.         if (file = fopen(path,"r")) {
  70.         empty = 0;
  71.         if (fscanf(file,"%d (%[^)]",&dummy,comm) == 2)
  72.             for (i = 0; i < names; i++) {
  73.             if (!sts[i].st_dev) {
  74.                 if (strcmp(namelist[i],comm)) continue;
  75.             }
  76.             else {
  77.                 sprintf(path,"%s/%d/exe",PROC_BASE,pid);
  78.                 if (stat(path,&st) < 0) continue;
  79.                 if (sts[i].st_dev != st.st_dev || sts[i].st_ino !=
  80.                   st.st_ino) continue;
  81.             }
  82.             if (interactive && !ask(comm,pid)) continue;
  83.             if (kill(pid,signal) >= 0) {
  84.                 if (verbose)
  85.                 fprintf(stderr,"Killed %s(%d)\n",comm,pid);
  86.                 found |= 1 << i;
  87.             }
  88.             else if (errno != ESRCH || interactive)
  89.                 fprintf(stderr,"%s(%d): %s\n",comm,pid,
  90.                   strerror(errno));
  91.             }
  92.         (void) fclose(file);
  93.         }
  94.     }
  95.     (void) closedir(dir);
  96.     if (empty) {
  97.     fprintf(stderr,PROC_BASE " is empty (not mounted ?)\n");
  98.     exit(1);
  99.     }
  100.     for (i = 0; i < names; i++)
  101.     if (!(found & (1 << i)))
  102.         fprintf(stderr,"%s: no process killed\n",namelist[i]);
  103.     return found == ((1 << (names-1)) | ((1 << (names-1))-1)) ? 0 : 1;
  104. }
  105.  
  106.  
  107. static void usage(void)
  108. {
  109.     fprintf(stderr,"usage: killall [ -iv ] [ -signal ] name ...\n");
  110.     fprintf(stderr,"       killall -l\n\n");
  111.     fprintf(stderr,"    -i      ask for confirmation before killing\n");
  112.     fprintf(stderr,"    -l      list all known signal names\n");
  113.     fprintf(stderr,"    -signal send signal instead of SIGTERM\n");
  114.     fprintf(stderr,"    -v      report if the signal was successfully sent\n\n"
  115.       );
  116.     exit(1);
  117. }
  118.  
  119.  
  120. int main(int argc,char **argv)
  121. {
  122.     int sig_num;
  123.  
  124.     if (argc == 2 && !strcmp(argv[1],"-l")) {
  125.     list_signals();
  126.     return 0;
  127.     }
  128.     sig_num = SIGTERM;
  129.     while (argc > 1 && *argv[1] == '-') {
  130.     argc--;
  131.     argv++;
  132.         if (!strcmp(*argv,"-v")) verbose = 1;
  133.     else if (!strcmp(*argv,"-i")) interactive = 1;
  134.     else if (!strcmp(*argv,"-vi") || !strcmp(*argv,"-iv"))
  135.         verbose = interactive = 1;
  136.     else sig_num = get_signal(*argv+1,"killall");
  137.     }
  138.     if (argc < 2) usage();
  139.     if (argc > MAX_NAMES+1) {
  140.     fprintf(stderr,"Maximum number of names is %d\n",MAX_NAMES);
  141.     exit(1);
  142.     }
  143.     return kill_all(sig_num,argc-1,argv+1);
  144. }
  145.