int main(int argc, char **argv) { char *arg = NULL; int opt; bool dryrun = false; RC_STRINGLIST *omits = rc_stringlist_new(); int sig = SIGKILL; char *here; char *token; /* Ensure that we are only quiet when explicitly told to be */ unsetenv("EINFO_QUIET"); applet = basename_c(argv[0]); rc_stringlist_addu(omits, "1"); while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1) { switch (opt) { case 'd': dryrun = true; break; case 'o': here = optarg; while ((token = strsep(&here, ",;:"))) { if ((pid_t) atoi(token) > 0) rc_stringlist_addu(omits, token); else { eerror("Invalid omit pid value %s", token); usage(EXIT_FAILURE); } } break; case_RC_COMMON_GETOPT } } if (argc > optind) { arg = argv[optind]; sig = atoi(arg); if (sig <= 0 || sig > 31) { rc_stringlist_free(omits); eerror("Invalid signal %s", arg); usage(EXIT_FAILURE); } } openlog(applet, LOG_CONS|LOG_PID, LOG_DAEMON); if (mount_proc() != 0) { rc_stringlist_free(omits); eerrorx("Unable to mount /proc file system"); } signal_processes(sig, omits, dryrun); rc_stringlist_free(omits); return 0; }
/* Main for either killall or pidof. */ int main(int argc, char **argv) { PROC *p; int pid, sid = -1; pid_t opid[KILLALL_OMITSZ]; int i, oind, omit = 0; int sig = SIGKILL; /* return non-zero if no process was killed */ int retval = 2; /* Get program name. */ if ((progname = strrchr(argv[0], '/')) == NULL) progname = argv[0]; else progname++; /* Now connect to syslog. */ openlog(progname, LOG_CONS|LOG_PID, LOG_DAEMON); /* Were we called as 'pidof' ? */ if (strcmp(progname, "pidof") == 0) return main_pidof(argc, argv); /* Right, so we are "killall". */ for (oind = KILLALL_OMITSZ-1; oind > 0; oind--) opid[oind] = 0; if (argc > 1) { for (i = 1; i < argc; i++) { if (argv[i][0] == '-') (argv[i])++; if (argv[i][0] == 'o') { if (++i >= argc) usage(); if (oind >= KILLALL_OMITSZ -1) { nsyslog(LOG_ERR,"omit pid buffer size " "%d exceeded!\n", KILLALL_OMITSZ); closelog(); exit(1); } if ((opid[oind] = atoi(argv[i])) < 1) { nsyslog(LOG_ERR, "illegal omit pid value " "(%s)!\n", argv[i]); closelog(); exit(1); } oind++; omit = 1; } else if ((sig = atoi(argv[1])) <= 0 || sig > 31) usage(); } } /* First get the /proc filesystem online. */ mount_proc(); /* * Ignoring SIGKILL and SIGSTOP do not make sense, but * someday kill(-1, sig) might kill ourself if we don't * do this. This certainly is a valid concern for SIGTERM- * Linux 2.1 might send the calling process the signal too. */ signal(SIGTERM, SIG_IGN); signal(SIGSTOP, SIG_IGN); signal(SIGKILL, SIG_IGN); /* lock us into memory */ mlockall(MCL_CURRENT | MCL_FUTURE); /* Now stop all processes. */ kill(-1, SIGSTOP); sent_sigstop = 1; /* Read /proc filesystem */ if (readproc(NO_STAT) < 0) { kill(-1, SIGCONT); return(1); } /* Now kill all processes except init (pid 1) and our session. */ sid = (int)getsid(0); pid = (int)getpid(); for (p = plist; p; p = p->next) { if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) continue; if (omit) { for (i = 0; i < oind; i++) if (opid[i] == p->pid) break; /* On a match, continue with the for loop above. */ if (i < oind) continue; } kill(p->pid, sig); retval = 0; } /* And let them continue. */ kill(-1, SIGCONT); /* Done. */ closelog(); /* Force the kernel to run the scheduler */ usleep(1); return retval; }