version 1.16, 2013/11/15 22:20:04 |
version 1.17, 2015/03/20 19:42:29 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
|
|
/* |
/* |
* Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 2009, 2015 Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
|
#define RENICE_NONE 0 |
|
#define RENICE_ABSOLUTE 1 |
|
#define RENICE_INCREMENT 2 |
|
|
struct renice_param { |
struct renice_param { |
int pri; |
int pri; |
int type; |
short pri_type; |
|
short id_type; |
id_t id; |
id_t id; |
}; |
}; |
|
|
|
|
{ |
{ |
struct renice_param *params, *p; |
struct renice_param *params, *p; |
struct passwd *pw; |
struct passwd *pw; |
int ch, type = PRIO_PROCESS; |
int ch, id_type = PRIO_PROCESS; |
int nflag = 0, pri = 0; |
int pri = 0, pri_type = RENICE_NONE; |
char *ep, *idstr; |
char *ep, *idstr; |
const char *errstr; |
const char *errstr; |
long l; |
|
|
|
if (argc < 3) |
if (argc < 3) |
usage(); |
usage(); |
|
|
/* Allocate enough space for the worst case. */ |
/* Allocate enough space for the worst case. */ |
params = p = calloc(argc - 1, sizeof(*params)); |
params = p = reallocarray(NULL, argc - 1, sizeof(*params)); |
if (params == NULL) |
if (params == NULL) |
err(1, NULL); |
err(1, NULL); |
|
|
/* Backwards compatibility: first arg may be priority. */ |
/* Backwards compatibility: first arg may be priority. */ |
if (isdigit((unsigned char)argv[1][0]) || |
if (isdigit((unsigned char)argv[1][0]) || |
(argv[1][0] == '-' && isdigit((unsigned char)argv[1][1]))) { |
((argv[1][0] == '+' || argv[1][0] == '-') && |
argv[0] = "-n"; |
isdigit((unsigned char)argv[1][1]))) { |
argc++; |
pri = (int)strtol(argv[1], &ep, 10); |
argv--; |
if (*ep != '\0' || ep == argv[1]) { |
|
warnx("invalid priority %s", argv[1]); |
|
usage(); |
|
} |
|
pri_type = RENICE_ABSOLUTE; |
|
optind = 2; |
} |
} |
|
|
/* |
/* |
|
|
if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) { |
if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'g': |
case 'g': |
type = PRIO_PGRP; |
id_type = PRIO_PGRP; |
idstr = optarg; |
idstr = optarg; |
break; |
break; |
case 'n': |
case 'n': |
l = strtol(optarg, &ep, 10); |
pri = (int)strtol(optarg, &ep, 10); |
if (*ep != '\0' || ep == optarg) { |
if (*ep != '\0' || ep == optarg) { |
warnx("invalid increment %s", optarg); |
warnx("invalid increment %s", optarg); |
usage(); |
usage(); |
} |
} |
pri = l > PRIO_MAX ? PRIO_MAX : |
|
l < PRIO_MIN ? PRIO_MIN : (int)l; |
|
|
|
/* Set priority for previous entries? */ |
/* Set priority for previous entries? */ |
if (!nflag) { |
if (pri_type == RENICE_NONE) { |
struct renice_param *pp; |
struct renice_param *pp; |
for (pp = params; pp != p; pp++) { |
for (pp = params; pp != p; pp++) { |
pp->pri = pri; |
pp->pri = pri; |
|
pp->pri_type = RENICE_INCREMENT; |
} |
} |
} |
} |
nflag = 1; |
pri_type = RENICE_INCREMENT; |
continue; |
continue; |
case 'p': |
case 'p': |
type = PRIO_PROCESS; |
id_type = PRIO_PROCESS; |
idstr = optarg; |
idstr = optarg; |
break; |
break; |
case 'u': |
case 'u': |
type = PRIO_USER; |
id_type = PRIO_USER; |
idstr = optarg; |
idstr = optarg; |
break; |
break; |
default: |
default: |
|
|
if (idstr == NULL) |
if (idstr == NULL) |
break; |
break; |
} |
} |
p->type = type; |
p->id_type = id_type; |
p->pri = pri; |
p->pri = pri; |
if (type == PRIO_USER) { |
p->pri_type = pri_type; |
|
if (id_type == PRIO_USER) { |
if ((pw = getpwnam(idstr)) == NULL) { |
if ((pw = getpwnam(idstr)) == NULL) { |
uid_t id = strtonum(idstr, 0, UID_MAX, &errstr); |
uid_t id = strtonum(idstr, 0, UID_MAX, &errstr); |
if (!errstr) |
if (!errstr) |
|
|
} |
} |
p++; |
p++; |
} |
} |
if (!nflag) |
if (pri_type == RENICE_NONE) |
usage(); |
usage(); |
exit(renice(params, p)); |
exit(renice(params, p)); |
} |
} |
|
|
static int |
static int |
renice(struct renice_param *p, struct renice_param *end) |
renice(struct renice_param *p, struct renice_param *end) |
{ |
{ |
int old, errors = 0; |
int new, old, errors = 0; |
|
|
for (; p < end; p++) { |
for (; p < end; p++) { |
errno = 0; |
errno = 0; |
old = getpriority(p->type, p->id); |
old = getpriority(p->id_type, p->id); |
if (errno) { |
if (errno) { |
warn("getpriority: %d", p->id); |
warn("getpriority: %d", p->id); |
errors++; |
errors++; |
continue; |
continue; |
} |
} |
if (setpriority(p->type, p->id, p->pri) == -1) { |
if (p->pri_type == RENICE_INCREMENT) |
|
p->pri += old; |
|
new = p->pri > PRIO_MAX ? PRIO_MAX : |
|
p->pri < PRIO_MIN ? PRIO_MIN : p->pri; |
|
if (setpriority(p->id_type, p->id, new) == -1) { |
warn("setpriority: %d", p->id); |
warn("setpriority: %d", p->id); |
errors++; |
errors++; |
continue; |
continue; |
} |
} |
printf("%d: old priority %d, new priority %d\n", |
printf("%d: old priority %d, new priority %d\n", |
p->id, old, p->pri); |
p->id, old, new); |
} |
} |
return (errors); |
return (errors); |
} |
} |