chiark / gitweb /
cgi-fcgi-interp: wip test program
[chiark-utils.git] / cprogs / usernice.c
1 /**/
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <sys/time.h>
8 #include <pwd.h>
9 #include <sys/resource.h>
10
11 int main(int argc,char **argv) {
12   long l;
13   int mrenice,wrenice,newprio,eflag;
14   uid_t ruid;
15   char *ep;
16   struct passwd *pw;
17
18   mrenice=0;
19   if (argc < 3) {
20     fputs("usernice: too few args\n"
21           " usage: usernice <nicelevel> <command> <arguments>\n"
22           "        usernice <nicelevel>p <pid> <pid> ...\n"
23           "        usernice <nicelevel>u <username|uid> ...\n",
24           stderr);
25     exit(-1);
26   }
27   l= strtol(*++argv,&ep,10);
28   if (*ep == 'p' || *ep == 'u') { mrenice= *ep++; }
29   if (*ep) { fputs("usernice: priority not numeric or bad flags\n",stderr); exit(-1); }
30   if (l<-20 || l>20)
31     { fputs("usernice: priority must be -20 .. 20\n",stderr); exit(-1); }
32   newprio= l;
33   if (mrenice) {
34     eflag=0;
35     while (*++argv) {
36       if (mrenice == 'p') {
37         wrenice= PRIO_PROCESS;
38         l= strtoul(*argv,&ep,10);
39         if (*ep) {
40           fprintf(stderr,"usernice: pid `%s' not numeric\n",*argv); eflag=2;
41           continue;
42         }
43       } else {
44         wrenice= PRIO_USER;
45         l= strtoul(*argv,&ep,10);
46         if (*ep) {
47           pw= getpwnam(*argv);
48           if (!pw) {
49             fprintf(stderr,"usernice: unknown user `%s'\n",*argv); eflag=2;
50             continue;
51           }
52           l= pw->pw_uid;
53         }
54       }
55       if (setpriority(wrenice,l,newprio)) {
56         perror(*argv); if (!eflag) eflag=1;
57       }
58     }
59     exit(eflag);
60   } else {
61     if (setpriority(PRIO_PROCESS,0,newprio))
62       { perror("usernice: setpriority"); exit(-1); }
63     ruid= getuid(); if (ruid == (uid_t)-1) { perror("usernice: getuid"); exit(-1); }
64     if (setreuid(ruid,ruid)) { perror("usernice: setreuid"); exit(-1); }
65     execvp(argv[1],argv+1); perror("usernice: exec"); exit(-1);
66   }
67 }