master xplshn/aruu / cmd / posix / renice.c
  1/* See LICENSE file for copyright and license details. */
  2
  3#include <sys/resource.h>
  4
  5#include <errno.h>
  6#include <pwd.h>
  7#include <stdlib.h>
  8
  9#include "util.h"
 10
 11#ifndef PRIO_MIN
 12#define PRIO_MIN -NZERO
 13#endif
 14
 15#ifndef PRIO_MAX
 16#define PRIO_MAX (NZERO - 1)
 17#endif
 18
 19static int
 20renice(int which, int who, long adj)
 21{
 22  errno = 0;
 23  adj += getpriority(which, who);
 24  if (errno) {
 25    weprintf("getpriority %d:", who);
 26    return 0;
 27  }
 28
 29  adj = MAX(PRIO_MIN, MIN(adj, PRIO_MAX));
 30  if (setpriority(which, who, (int)adj) < 0) {
 31    weprintf("setpriority %d:", who);
 32    return 0;
 33  }
 34
 35  return 1;
 36}
 37
 38static void
 39usage(void)
 40{
 41  eprintf("usage: %s -n num [-g | -p | -u] id ...\n", argv0);
 42}
 43
 44// ?man renice: alter priority of processes
 45// ?man arguments: -n num id ...
 46// ?man change the scheduling priority of running processes
 47int
 48main(int argc, char *argv[])
 49{
 50  const char    *adj = NULL;
 51  long           val;
 52  int            which = PRIO_PROCESS, ret = 0;
 53  struct passwd *pw;
 54  int            who;
 55
 56  ARGBEGIN
 57  {
 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  }
 77  ARGEND
 78
 79  if (!argc || !adj)
 80    usage();
 81
 82  val = estrtonum(adj, PRIO_MIN, PRIO_MAX);
 83  for (; *argv; argc--, argv++) {
 84    if (which == PRIO_USER) {
 85      errno = 0;
 86      if (!(pw = getpwnam(*argv))) {
 87        if (errno)
 88          weprintf("getpwnam %s:", *argv);
 89        else
 90          weprintf("getpwnam %s: no user found\n", *argv);
 91        ret = 1;
 92        continue;
 93      }
 94      who = pw->pw_uid;
 95    } else {
 96      who = estrtonum(*argv, 1, INT_MAX);
 97    }
 98    if (!renice(which, who, val))
 99      ret = 1;
100  }
101
102  return ret;
103}