⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skill.c

📁 Linux下进程监控相关源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1998 by Albert Cahalan; all rights resered. * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */#include <fcntl.h>#include <pwd.h>#include <dirent.h>#include <errno.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/resource.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>static int f_flag, i_flag, v_flag, w_flag, n_flag;static int tty_count, uid_count, cmd_count, pid_count;static int *ttys;static int *uids;static char **cmds;static int *pids;#define ENLIST(thing,addme) do{ \if(!thing##s) thing##s = malloc(sizeof(*thing##s)*saved_argc); \if(!thing##s) fprintf(stderr,"No memory.\n"),exit(2); \thing##s[thing##_count++] = addme; \}while(0)static int my_pid;static int saved_argc;static char **saved_argv;static int sig_or_pri;static int program;#define PROG_GARBAGE 0  /* keep this 0 */#define PROG_KILL  1#define PROG_SKILL 2/* #define PROG_NICE  3 */ /* easy, but the old one isn't broken */#define PROG_SNICE 4/***********************************************************************//* Linux signals: * * SIGSYS is required by Unix98. * SIGEMT is part of SysV, BSD, and ancient UNIX tradition. * * They are provided by these Linux ports: alpha, mips, sparc, and sparc64. * You get SIGSTKFLT and SIGUNUSED instead on i386, m68k, ppc, and arm. * (this is a Linux & libc bug -- both must be fixed) * * Total garbage: SIGIO SIGINFO SIGIOT SIGLOST SIGCLD * Nearly garbage: SIGSTKFLT SIGUNUSED (nothing else to fill slots) */#ifdef SIGSYS#  undef SIGUNUSED#  undef SIGSTKFLT#endif#ifndef SIGRTMIN#  define SIGRTMIN 32#endifint sigvals[] = {SIGABRT,SIGALRM,SIGBUS,SIGCHLD,SIGCONT,#ifdef SIGEMTSIGEMT,#endifSIGFPE,SIGHUP,SIGILL,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,#ifdef SIGPWRSIGPWR,#endifSIGQUIT,SIGSEGV,#ifdef SIGSTKFLTSIGSTKFLT,#endifSIGSTOP,#ifdef SIGSYSSIGSYS,#endifSIGTERM,SIGTRAP,SIGTSTP,SIGTTIN,SIGTTOU,#ifdef SIGUNUSEDSIGUNUSED,#endifSIGURG,SIGUSR1,SIGUSR2,SIGVTALRM,SIGWINCH,SIGXCPU,SIGXFSZ,};char *signames[] = {"ABRT","ALRM","BUS","CHLD","CONT",#ifdef SIGEMT"EMT",#endif"FPE","HUP","ILL","INT","KILL","PIPE","POLL","PROF","PWR","QUIT","SEGV",#ifdef SIGSTKFLT"STKFLT",#endif"STOP",#ifdef SIGSYS"SYS",#endif"TERM","TRAP","TSTP","TTIN","TTOU",#ifdef SIGUNUSED"UNUSED",#endif"URG","USR1","USR2","VTALRM","WINCH","XCPU","XFSZ"};const int number_of_signals = sizeof(sigvals)/sizeof(int);static int compare_signal_names(const void *a, const void *b){  return strcasecmp(*(char**)a,*(char**)b);}static int signal_name_to_number(char *name){  const char **ptr;  if(!strncasecmp(name,"SIG",3)) name += 3;  ptr = bsearch(&name, signames, number_of_signals,     sizeof(char *), compare_signal_names  );  if(!ptr){    long val;    char *endp;    val = strtol(name,&endp,10);    if(*endp) return -1; /* not valid */    if(val>127) return -1; /* not valid */    return val;  }  return sigvals[((unsigned long)ptr-(unsigned long)signames)/sizeof(char *)];}static const char *signal_name(int signo){  static char buf[32];  int n = number_of_signals;  signo &= 0x7f; /* need to process exit values too */  while(n--){    if(sigvals[n]==signo) return signames[n];  }  if(signo) sprintf(buf, "RTMIN+%d", signo-SIGRTMIN);  else      strcpy(buf,"0");  /* AIX would use "NULL" */  return buf;}static void pretty_print_signals(void){  int i = 0;  while(++i <= number_of_signals){    int n;    n = printf("%2d %s", i, signal_name(i));    if(i%7) printf("           \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + n);    else printf("\n");  }  if((i-1)%7) printf("\n");}static void unix_print_signals(void){  int pos = 0;  int i = 0;  while(++i <= number_of_signals){    if(i-1) printf("%c", (pos>73)?(pos=0,'\n'):(pos++,' ') );    pos += printf("%s", signal_name(i));  }  printf("\n");}/********************************************************************//* This is junk of course, to be replaced soon */const char *uid_to_user(int uid){  static struct passwd *p;  static char txt[64];  p = getpwuid(uid);  if(p) return p->pw_name;  sprintf(txt, "%d", uid);  return txt;}/* this must be replaced soon... */const char *dev_to_tty(int tty){  static char txt[64];  sprintf(txt, "%d,%d", (tty>>8)&0xff, tty&0xff);  return txt;}/********************************************************************//***** kill or nice a process */static void hurt_proc(int tty, int user, int pid, char *cmd){  int failed;  int saved_errno;  if(i_flag){    char buf[8];    fprintf(stderr, "%-8.8s %-8.8s %5d %-16.16s   ? ",      dev_to_tty(tty),uid_to_user(user),pid,cmd    );    if(!fgets(buf,7,stdin)){      printf("\n");      exit(0);    }    if(*buf!='y' && *buf!='Y') return;  }  /* do the actual work */  if(program==PROG_SKILL) failed=kill(pid,sig_or_pri);  else                    failed=setpriority(PRIO_PROCESS,pid,sig_or_pri);  saved_errno = errno;  if(w_flag && failed){    fprintf(stderr, "%-8.8s %-8.8s %5d %-16.16s   ",      dev_to_tty(tty),uid_to_user(user),pid,cmd    );    errno = saved_errno;    perror("");    return;  }  if(i_flag) return;  if(v_flag){    printf("%-8.8s %-8.8s %5d %-16.16s\n",      dev_to_tty(tty),uid_to_user(user),pid,cmd    );    return;  }  if(n_flag){   printf("%d\n",pid);   return;  }}/***** check one process */static void check_proc(int pid){  char buf[128];  struct stat statbuf;  char *tmp;  int tty;  int fd;  int i;  if(pid==my_pid) return;  sprintf(buf, "/proc/%d/stat", pid); /* pid (cmd) state ppid pgrp session tty */  fd = open(buf,O_RDONLY);  if(fd==-1){  /* process exited maybe */    if(pids && w_flag) printf("WARNING: process %d could not be found.",pid);    return;  }  fstat(fd, &statbuf);  if(uids){  /* check the EUID */    i=uid_count;    while(i--) if(uids[i]==statbuf.st_uid) break;    if(i==-1) goto closure;  }  read(fd,buf,128);  buf[127] = '\0';  tmp = strrchr(buf, ')');  *tmp++ = '\0';  i = 5; while(i--) while(*tmp++!=' '); /* scan to find tty */  tty = atoi(tmp);  if(ttys){    i=tty_count;    while(i--) if(ttys[i]==tty) break;    if(i==-1) goto closure;  }  tmp = strchr(buf, '(') + 1;  if(cmds){    i=cmd_count;    /* fast comparison trick -- useful? */    while(i--) if(cmds[i][0]==*tmp && !strcmp(cmds[i],tmp)) break;    if(i==-1) goto closure;  }  /* This is where we kill/nice something. *//*  fprintf(stderr, "PID %d, UID %d, TTY %d,%d, COMM %s\n",    pid, statbuf.st_uid, tty>>8, tty&0xf, tmp  );*/  hurt_proc(tty, statbuf.st_uid, pid, tmp);closure:  close(fd); /* kill/nice _first_ to avoid PID reuse */}/***** debug function */#if 0static void show_lists(void){  int i;  fprintf(stderr, "%d TTY: ", tty_count);  if(ttys){    i=tty_count;    while(i--){      fprintf(stderr, "%d,%d%c", (ttys[i]>>8)&0xff, ttys[i]&0xff, i?' ':'\n');    }  }else fprintf(stderr, "\n");    fprintf(stderr, "%d UID: ", uid_count);  if(uids){    i=uid_count;    while(i--) fprintf(stderr, "%d%c", uids[i], i?' ':'\n');  }else fprintf(stderr, "\n");    fprintf(stderr, "%d PID: ", pid_count);  if(pids){    i=pid_count;    while(i--) fprintf(stderr, "%d%c", pids[i], i?' ':'\n');  }else fprintf(stderr, "\n");    fprintf(stderr, "%d CMD: ", cmd_count);  if(cmds){    i=cmd_count;    while(i--) fprintf(stderr, "%s%c", cmds[i], i?' ':'\n');  }else fprintf(stderr, "\n");}#endif/***** iterate over all PIDs */static void iterate(void){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -