mirror of
git://git.suckless.org/sbase
synced 2024-12-28 10:02:26 +00:00
ec8246bbc6
It actually makes the binaries smaller, the code easier to read (gems like "val == true", "val == false" are gone) and actually predictable in the sense of that we actually know what we're working with (one bitwise operator was quite adventurous and should now be fixed). This is also more consistent with the other suckless projects around which don't use boolean types.
117 lines
1.9 KiB
C
117 lines
1.9 KiB
C
/* See LICENSE file for copyright and license details. */
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <pwd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/resource.h>
|
|
|
|
#include "util.h"
|
|
|
|
static int strtop(const char *);
|
|
static int renice(int, int, long);
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
eprintf("renice -n inc [-g | -p | -u] ID ...\n");
|
|
}
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
const char *adj = NULL;
|
|
long val;
|
|
int i, which = PRIO_PROCESS, status = 0;
|
|
|
|
ARGBEGIN {
|
|
case 'n':
|
|
adj = EARGF(usage());
|
|
break;
|
|
case 'g':
|
|
which = PRIO_PGRP;
|
|
break;
|
|
case 'p':
|
|
which = PRIO_PROCESS;
|
|
break;
|
|
case 'u':
|
|
which = PRIO_USER;
|
|
break;
|
|
default:
|
|
usage();
|
|
break;
|
|
} ARGEND;
|
|
|
|
if (argc == 0 || !adj)
|
|
usage();
|
|
|
|
val = estrtol(adj, 10);
|
|
for (i = 0; i < argc; i++) {
|
|
int who = -1;
|
|
|
|
if (which == PRIO_USER) {
|
|
const struct passwd *pwd;
|
|
|
|
errno = 0;
|
|
do pwd = getpwnam(argv[i]); while (errno == EINTR);
|
|
|
|
if (pwd)
|
|
who = pwd->pw_uid;
|
|
else if (errno != 0) {
|
|
perror("can't read passwd");
|
|
status = 1;
|
|
continue;
|
|
}
|
|
}
|
|
if (who < 0)
|
|
who = strtop(argv[i]);
|
|
|
|
if (who < 0 || !renice(which, who, val))
|
|
status = 1;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static int
|
|
strtop(const char *s)
|
|
{
|
|
char *end;
|
|
long n;
|
|
|
|
errno = 0;
|
|
n = strtol(s, &end, 10);
|
|
if (*end != '\0') {
|
|
fprintf(stderr, "%s: not an integer\n", s);
|
|
return -1;
|
|
}
|
|
if (errno != 0 || n <= 0 || n > INT_MAX) {
|
|
fprintf(stderr, "%s: invalid value\n", s);
|
|
return -1;
|
|
}
|
|
|
|
return (int)n;
|
|
}
|
|
|
|
static int
|
|
renice(int which, int who, long adj)
|
|
{
|
|
errno = 0;
|
|
adj += getpriority(which, who);
|
|
if (errno != 0) {
|
|
fprintf(stderr, "can't get %d nice level: %s\n",
|
|
who, strerror(errno));
|
|
return 0;
|
|
}
|
|
|
|
adj = MAX(-NZERO, MIN(adj, NZERO - 1));
|
|
if (setpriority(which, who, (int)adj) == -1) {
|
|
fprintf(stderr, "can't set %d nice level: %s\n",
|
|
who, strerror(errno));
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|