skill: add long options & new debugging option
Done for skillsnice_parse(), meaning the kill needs functionality will be done later. This commit also introduces new debugging option. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
61094186fe
commit
991b8a94f0
248
skill.c
248
skill.c
@ -9,6 +9,7 @@
|
|||||||
* GNU Library General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*/
|
*/
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@ -97,7 +98,7 @@ static void hurt_proc(int tty, int uid, int pid, const char *restrict const cmd,
|
|||||||
else
|
else
|
||||||
failed = setpriority(PRIO_PROCESS, pid, sig_or_pri);
|
failed = setpriority(PRIO_PROCESS, pid, sig_or_pri);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
if (run_time->warnings && failed) {
|
if ((run_time->warnings && failed) || run_time->debugging) {
|
||||||
fprintf(stderr, "%-8s %-8s %5d %-16.16s ",
|
fprintf(stderr, "%-8s %-8s %5d %-16.16s ",
|
||||||
(char *)dn_buf, user_from_uid(uid), pid, cmd);
|
(char *)dn_buf, user_from_uid(uid), pid, cmd);
|
||||||
errno = saved_errno;
|
errno = saved_errno;
|
||||||
@ -126,7 +127,7 @@ static void check_proc(int pid, struct run_time_conf_t *run_time)
|
|||||||
int tty;
|
int tty;
|
||||||
int fd;
|
int fd;
|
||||||
int i;
|
int i;
|
||||||
if (pid == my_pid)
|
if (pid == my_pid || pid == 0)
|
||||||
return;
|
return;
|
||||||
/* pid (cmd) state ppid pgrp session tty */
|
/* pid (cmd) state ppid pgrp session tty */
|
||||||
sprintf(buf, "/proc/%d/stat", pid);
|
sprintf(buf, "/proc/%d/stat", pid);
|
||||||
@ -191,6 +192,8 @@ static void show_lists(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
fprintf(stderr, _("signal: %d\n"), sig_or_pri);
|
||||||
|
|
||||||
fprintf(stderr, _("%d TTY: "), tty_count);
|
fprintf(stderr, _("%d TTY: "), tty_count);
|
||||||
if (ttys) {
|
if (ttys) {
|
||||||
i = tty_count;
|
i = tty_count;
|
||||||
@ -481,125 +484,99 @@ int skill_sig_option(int *argc, char **argv)
|
|||||||
return signo;
|
return signo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NO_PRI_VAL ((int)0xdeafbeef)
|
|
||||||
static void skillsnice_parse(int argc,
|
static void skillsnice_parse(int argc,
|
||||||
char ** argv,
|
char **argv, struct run_time_conf_t *run_time)
|
||||||
struct run_time_conf_t *run_time)
|
|
||||||
{
|
{
|
||||||
int signo = -1;
|
int signo = -1;
|
||||||
int prino = NO_PRI_VAL;
|
int prino = DEFAULT_NICE;
|
||||||
int force = 0;
|
int force = 0;
|
||||||
int num_found = 0;
|
int num_found = 0;
|
||||||
|
int ch, i;
|
||||||
const char *restrict argptr;
|
const char *restrict argptr;
|
||||||
|
|
||||||
|
static const struct option longopts[] = {
|
||||||
|
{"command", required_argument, NULL, 'c'},
|
||||||
|
{"debug", no_argument, NULL, 'd'},
|
||||||
|
{"fast", no_argument, NULL, 'f'},
|
||||||
|
{"interactive", no_argument, NULL, 'i'},
|
||||||
|
{"list", no_argument, NULL, 'l'},
|
||||||
|
{"no-action", no_argument, NULL, 'n'},
|
||||||
|
{"pid", required_argument, NULL, 'p'},
|
||||||
|
{"table", no_argument, NULL, 'L'},
|
||||||
|
{"tty", required_argument, NULL, 't'},
|
||||||
|
{"user", required_argument, NULL, 'u'},
|
||||||
|
{"verbose", no_argument, NULL, 'v'},
|
||||||
|
{"warnings", no_argument, NULL, 'w'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"version", no_argument, NULL, 'V'},
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
skillsnice_usage();
|
skillsnice_usage();
|
||||||
|
|
||||||
|
sig_or_pri = -1;
|
||||||
|
|
||||||
if (program == PROG_SNICE)
|
if (program == PROG_SNICE)
|
||||||
prino = snice_prio_option(&argc, argv);
|
prino = snice_prio_option(&argc, argv);
|
||||||
else if (program == PROG_SKILL)
|
else if (program == PROG_SKILL) {
|
||||||
signo = skill_sig_option(&argc, argv);
|
signo = skill_sig_option(&argc, argv);
|
||||||
|
if (-1 < signo)
|
||||||
|
sig_or_pri = signo;
|
||||||
|
}
|
||||||
|
|
||||||
if (argc == 2 && argv[1][0] == '-') {
|
pid_count = 0;
|
||||||
if (!strcmp(argv[1], "-L")) {
|
|
||||||
pretty_print_signals();
|
while ((ch =
|
||||||
exit(0);
|
getopt_long(argc, argv, "c:dfilnp:Lt:u:vwhV", longopts,
|
||||||
}
|
NULL)) != -1)
|
||||||
if (!strcmp(argv[1], "-l")) {
|
switch (ch) {
|
||||||
unix_print_signals();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
|
|
||||||
display_kill_version();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
skillsnice_usage();
|
|
||||||
}
|
|
||||||
NEXTARG;
|
|
||||||
/* Time for serious parsing. What does "skill -int 123 456" mean? */
|
|
||||||
while (argc) {
|
|
||||||
if (force && !num_found) {
|
|
||||||
/* if forced, _must_ find something */
|
|
||||||
fprintf(stderr, _("ERROR: -%c used with bad data.\n"),
|
|
||||||
force);
|
|
||||||
skillsnice_usage();
|
|
||||||
}
|
|
||||||
force = 0;
|
|
||||||
/* If '-' found, collect any flags. (but lone "-" is a tty) */
|
|
||||||
if (*argptr == '-' && argptr[1]) {
|
|
||||||
argptr++;
|
|
||||||
do {
|
|
||||||
switch ((force = *argptr++)) {
|
|
||||||
default:
|
|
||||||
skillsnice_usage();
|
|
||||||
case 't':
|
|
||||||
case 'u':
|
|
||||||
case 'p':
|
|
||||||
case 'c':
|
case 'c':
|
||||||
if (!*argptr) {
|
ENLIST(cmd, optarg);
|
||||||
/* nothing left here, *argptr is '\0' */
|
break;
|
||||||
if (!NEXTARG) {
|
case 'd':
|
||||||
fprintf(stderr,
|
run_time->debugging = 1;
|
||||||
_
|
break;
|
||||||
("ERROR: -%c with nothing after it.\n"),
|
|
||||||
force);
|
|
||||||
skillsnice_usage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto selection_collection;
|
|
||||||
case 'f':
|
case 'f':
|
||||||
run_time->fast++;
|
run_time->fast = 1;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
run_time->interactive++;
|
run_time->interactive = 1;
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
run_time->verbose++;
|
|
||||||
break;
|
|
||||||
case 'w':
|
|
||||||
run_time->warnings++;
|
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
unix_print_signals();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
case 'n':
|
case 'n':
|
||||||
run_time->noaction++;
|
run_time->noaction = 1;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 'p':
|
||||||
NEXTARG;
|
ENLIST(pid,
|
||||||
/*
|
strtol_or_err(optarg,
|
||||||
* If no more arguments, all the
|
_("failed to parse argument")));
|
||||||
* "if(argc)..." tests will fail and
|
pid_count++;
|
||||||
* the big loop will exit.
|
break;
|
||||||
*/
|
case 'L':
|
||||||
} /* END OF SWITCH */
|
pretty_print_signals();
|
||||||
} while (force);
|
exit(EXIT_SUCCESS);
|
||||||
} /* END OF IF */
|
|
||||||
selection_collection:
|
|
||||||
num_found = 0; /* we should find at least one thing */
|
|
||||||
switch (force) {
|
|
||||||
/* fall through each data type */
|
|
||||||
default:
|
|
||||||
skillsnice_usage();
|
|
||||||
case 0: /* not forced */
|
|
||||||
if (argptr && argptr[0] == '-')
|
|
||||||
/* its the next argument not a parameter */
|
|
||||||
continue;
|
|
||||||
case 't':
|
case 't':
|
||||||
if (argc) {
|
{
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
char path[32];
|
char path[32];
|
||||||
if (!argptr)
|
if (!optarg)
|
||||||
/* Huh? Maybe "skill -t ''". */
|
/* Huh? Maybe "skill -t ''". */
|
||||||
skillsnice_usage();
|
skillsnice_usage();
|
||||||
snprintf(path, 32, "/dev/%s", argptr);
|
snprintf(path, 32, "/dev/%s", optarg);
|
||||||
if (stat(path, &sbuf) >= 0
|
if (stat(path, &sbuf) >= 0
|
||||||
&& S_ISCHR(sbuf.st_mode)) {
|
&& S_ISCHR(sbuf.st_mode)) {
|
||||||
num_found++;
|
num_found++;
|
||||||
ENLIST(tty, sbuf.st_rdev);
|
ENLIST(tty, sbuf.st_rdev);
|
||||||
if (!NEXTARG)
|
if (!NEXTARG)
|
||||||
break;
|
break;
|
||||||
} else if (!(argptr[1])) {
|
} else if (!(optarg[1])) {
|
||||||
/* if only 1 character */
|
/* if only 1 character */
|
||||||
switch (*argptr) {
|
switch (*optarg) {
|
||||||
default:
|
default:
|
||||||
if (stat(argptr, &sbuf) < 0)
|
if (stat(optarg, &sbuf) < 0)
|
||||||
/* the shell eats '?' */
|
/* the shell eats '?' */
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
@ -611,10 +588,9 @@ static void skillsnice_parse(int argc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (force)
|
break;
|
||||||
continue;
|
|
||||||
case 'u':
|
case 'u':
|
||||||
if (argc) {
|
{
|
||||||
struct passwd *passwd_data;
|
struct passwd *passwd_data;
|
||||||
passwd_data = getpwnam(argptr);
|
passwd_data = getpwnam(argptr);
|
||||||
if (passwd_data) {
|
if (passwd_data) {
|
||||||
@ -624,68 +600,52 @@ static void skillsnice_parse(int argc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (force)
|
|
||||||
continue;
|
|
||||||
case 'p':
|
|
||||||
if (argc && *argptr >= '0' && *argptr <= '9') {
|
|
||||||
char *endp;
|
|
||||||
int num;
|
|
||||||
num = strtol(argptr, &endp, 0);
|
|
||||||
if (*endp == '\0') {
|
|
||||||
num_found++;
|
|
||||||
ENLIST(pid, num);
|
|
||||||
if (!NEXTARG)
|
|
||||||
break;
|
break;
|
||||||
}
|
case 'v':
|
||||||
}
|
run_time->verbose = 1;
|
||||||
if (force)
|
|
||||||
continue;
|
|
||||||
if (num_found)
|
|
||||||
/* could still be an option */
|
|
||||||
continue;
|
|
||||||
case 'c':
|
|
||||||
if (argc) {
|
|
||||||
num_found++;
|
|
||||||
ENLIST(cmd, argptr);
|
|
||||||
if (!NEXTARG)
|
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
run_time->warnings = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
skillsnice_usage();
|
||||||
|
case 'V':
|
||||||
|
display_kill_version();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
default:
|
||||||
|
skillsnice_usage();
|
||||||
}
|
}
|
||||||
} /* END OF SWITCH */
|
|
||||||
} /* END OF WHILE */
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
ENLIST(pid, strtol_or_err(argv[0],
|
||||||
|
_("failed to parse argument")));
|
||||||
|
pid_count++;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
/* No more arguments to process. Must sanity check. */
|
/* No more arguments to process. Must sanity check. */
|
||||||
if (!tty_count && !uid_count && !cmd_count && !pid_count) {
|
if (!tty_count && !uid_count && !cmd_count && !pid_count)
|
||||||
fprintf(stderr, _("ERROR: no process selection criteria.\n"));
|
errx(EXIT_FAILURE, _("no process selection criteria"));
|
||||||
skillsnice_usage();
|
if ((run_time->fast | run_time->interactive | run_time->
|
||||||
}
|
verbose | run_time->warnings | run_time->noaction) & ~1)
|
||||||
if ((run_time->fast | run_time->interactive | run_time->verbose | run_time->warnings | run_time->noaction) & ~1) {
|
errx(EXIT_FAILURE, _("general flags may not be repeated"));
|
||||||
fprintf(stderr,
|
if (run_time->interactive
|
||||||
_("ERROR: general flags may not be repeated.\n"));
|
&& (run_time->verbose | run_time->fast | run_time->noaction))
|
||||||
skillsnice_usage();
|
errx(EXIT_FAILURE, _("-i makes no sense with -v, -f, and -n"));
|
||||||
}
|
if (run_time->verbose && (run_time->interactive | run_time->fast))
|
||||||
if (run_time->interactive && (run_time->verbose | run_time->fast | run_time->noaction)) {
|
errx(EXIT_FAILURE, _("-v makes no sense with -i and -f"));
|
||||||
fprintf(stderr,
|
|
||||||
_("ERROR: -i makes no sense with -v, -f, and -n.\n"));
|
|
||||||
skillsnice_usage();
|
|
||||||
}
|
|
||||||
if (run_time->verbose && (run_time->interactive | run_time->fast)) {
|
|
||||||
fprintf(stderr,
|
|
||||||
_("ERROR: -v makes no sense with -i and -f.\n"));
|
|
||||||
skillsnice_usage();
|
|
||||||
}
|
|
||||||
/* OK, set up defaults */
|
|
||||||
if (prino == NO_PRI_VAL)
|
|
||||||
prino = DEFAULT_NICE;
|
|
||||||
if (signo < 0)
|
|
||||||
signo = SIGTERM;
|
|
||||||
if (run_time->noaction) {
|
if (run_time->noaction) {
|
||||||
program = PROG_SKILL;
|
program = PROG_SKILL;
|
||||||
/* harmless */
|
/* harmless */
|
||||||
signo = 0;
|
sig_or_pri = 0;
|
||||||
}
|
}
|
||||||
if (program == PROG_SKILL)
|
if (program == PROG_SNICE)
|
||||||
sig_or_pri = signo;
|
|
||||||
else
|
|
||||||
sig_or_pri = prino;
|
sig_or_pri = prino;
|
||||||
|
else if (sig_or_pri < 0)
|
||||||
|
sig_or_pri = SIGTERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* main body */
|
/* main body */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user