1/* See LICENSE file for copyright and license details. */
2
3
4#include <sys/resource.h>
5
6#include <errno.h>
7#include <pwd.h>
8#include <stdlib.h>
9
10#include "util.h"
11
12#ifndef PRIO_MIN
13#define PRIO_MIN -NZERO
14#endif
15
16#ifndef PRIO_MAX
17#define PRIO_MAX (NZERO-1)
18#endif
19
20static int
21renice(int which, int who, long adj)
22{
23 errno = 0;
24 adj += getpriority(which, who);
25 if (errno) {
26 weprintf("getpriority %d:", who);
27 return 0;
28 }
29
30 adj = MAX(PRIO_MIN, MIN(adj, PRIO_MAX));
31 if (setpriority(which, who, (int)adj) < 0) {
32 weprintf("setpriority %d:", who);
33 return 0;
34 }
35
36 return 1;
37}
38
39static void
40usage(void)
41{
42 eprintf("usage: %s -n num [-g | -p | -u] id ...\n", argv0);
43}
44
45// ?man renice: alter priority of processes
46// ?man arguments: -n num id ...
47// ?man change the scheduling priority of running processes
48int
49main(int argc, char *argv[])
50{
51 const char *adj = NULL;
52 long val;
53 int which = PRIO_PROCESS, ret = 0;
54 struct passwd *pw;
55 int who;
56
57 ARGBEGIN {
58 // ?man -n:str: print line numbers or counts
59 case 'n':
60 adj = EARGF(usage());
61 break;
62 // ?man -g: specify option flag
63 case 'g':
64 which = PRIO_PGRP;
65 break;
66 // ?man -p: preserve file attributes
67 case 'p':
68 which = PRIO_PROCESS;
69 break;
70 // ?man -u: unbuffered output
71 case 'u':
72 which = PRIO_USER;
73 break;
74 default:
75 usage();
76 } ARGEND
77
78 if (!argc || !adj)
79 usage();
80
81 val = estrtonum(adj, PRIO_MIN, PRIO_MAX);
82 for (; *argv; argc--, argv++) {
83 if (which == PRIO_USER) {
84 errno = 0;
85 if (!(pw = getpwnam(*argv))) {
86 if (errno)
87 weprintf("getpwnam %s:", *argv);
88 else
89 weprintf("getpwnam %s: no user found\n", *argv);
90 ret = 1;
91 continue;
92 }
93 who = pw->pw_uid;
94 } else {
95 who = estrtonum(*argv, 1, INT_MAX);
96 }
97 if (!renice(which, who, val))
98 ret = 1;
99 }
100
101 return ret;
102}