[BACK]Return to renice.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / renice

Diff for /src/usr.bin/renice/renice.c between version 1.12 and 1.13

version 1.12, 2007/03/16 16:36:06 version 1.13, 2008/12/08 21:23:10
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
   
 /*  /*
  * Copyright (c) 1983, 1989, 1993   * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
  *      The Regents of the University of California.  All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * Permission to use, copy, modify, and distribute this software for any
  * modification, are permitted provided that the following conditions   * purpose with or without fee is hereby granted, provided that the above
  * are met:   * copyright notice and this permission notice appear in all copies.
  * 1. Redistributions of source code must retain the above copyright  
  *    notice, this list of conditions and the following disclaimer.  
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice, this list of conditions and the following disclaimer in the  
  *    documentation and/or other materials provided with the distribution.  
  * 3. Neither the name of the University nor the names of its contributors  
  *    may be used to endorse or promote products derived from this software  
  *    without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  
  * SUCH DAMAGE.  
  */   */
   
 #ifndef lint  #ifndef lint
 static char copyright[] =  static const char rcsid[] = "$OpenBSD$";
 "@(#) Copyright (c) 1983, 1989, 1993\n\  
         The Regents of the University of California.  All rights reserved.\n";  
 #endif /* not lint */  #endif /* not lint */
   
 #ifndef lint  
 #if 0  
 static char sccsid[] = "@(#)renice.c    8.1 (Berkeley) 6/9/93";  
 #else  
 static char rcsid[] = "$OpenBSD$";  
 #endif  
 #endif /* not lint */  
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/resource.h>  #include <sys/resource.h>
   
   #include <ctype.h>
   #include <err.h>
   #include <errno.h>
   #include <limits.h>
   #include <pwd.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <pwd.h>  
 #include <err.h>  
 #include <errno.h>  
   
   struct renice_param {
           int pri;
           int type;
           id_t id;
   };
   
 int main(int, char **);  int main(int, char **);
 int donice(int, uid_t, int);  static int renice(struct renice_param *, struct renice_param *);
 void usage(void);  __dead void usage(void);
   
 /*  
  * Change the priority (nice) of processes  
  * or groups of processes which are already  
  * running.  
  */  
 int  int
 main(int argc, char *argv[])  main(int argc, char **argv)
 {  {
         int which = PRIO_PROCESS;          struct renice_param *params, *p;
         int errs = 0;          struct passwd *pw;
         long prio, who = 0;          int ch, type = PRIO_PROCESS;
         char *ep;          int nflag = 0, pri = 0;
           char *ep, *idstr;
           const char *errstr;
           long l;
   
         argc--, argv++;          if (argc < 3)
         if (argc < 2)  
                 usage();                  usage();
         prio = strtol(*argv, &ep, 10);  
         if (*ep != NULL)          /* Allocate enough space for the worst case. */
                 usage();          params = p = calloc(argc - 1, sizeof(*params));
         argc--, argv++;          if (params == NULL)
         if (prio > PRIO_MAX)                  err(1, NULL);
                 prio = PRIO_MAX;  
         if (prio < PRIO_MIN)          /* Backwards compatibility: first arg may be priority. */
                 prio = PRIO_MIN;          if (isdigit((unsigned char)argv[1][0])) {
         for (; argc > 0; argc--, argv++) {                  argv[0] = "-n";
                 if (strcmp(*argv, "-g") == 0) {                  argc++;
                         which = PRIO_PGRP;                  argv--;
                         continue;          }
   
           /*
            * Slightly tricky getopt() usage since it is legal to have
            * option flags interleaved with arguments.
            */
           for (;;) {
                   if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) {
                           switch (ch) {
                           case 'g':
                                   type = PRIO_PGRP;
                                   idstr = optarg;
                                   break;
                           case 'n':
                                   l = strtol(optarg, &ep, 10);
                                   if (*ep != '\0' || ep == optarg) {
                                           warnx("invalid increment %s", optarg);
                                           usage();
                                   }
                                   pri = l > PRIO_MAX ? PRIO_MAX :
                                       l < PRIO_MIN ? PRIO_MIN : (int)l;
   
                                   /* Set priority for previous entries? */
                                   if (!nflag) {
                                           struct renice_param *pp;
                                           for (pp = params; pp != p; pp++) {
                                                   pp->pri = pri;
                                           }
                                   }
                                   nflag = 1;
                                   continue;
                           case 'p':
                                   type = PRIO_PROCESS;
                                   idstr = optarg;
                                   break;
                           case 'u':
                                   type = PRIO_USER;
                                   idstr = optarg;
                                   break;
                           default:
                                   usage();
                                   break;
                           }
                   } else {
                           idstr = argv[optind++];
                           if (idstr == NULL)
                                   break;
                 }                  }
                 if (strcmp(*argv, "-u") == 0) {                  p->type = type;
                         which = PRIO_USER;                  p->pri = pri;
                         continue;                  if (type == PRIO_USER) {
                 }                          if ((pw = getpwnam(idstr)) == NULL) {
                 if (strcmp(*argv, "-p") == 0) {                                  uid_t id = strtonum(idstr, 0, UID_MAX, &errstr);
                         which = PRIO_PROCESS;                                  if (!errstr)
                         continue;                                          pw = getpwuid(id);
                 }                          }
                 if (which == PRIO_USER) {                          if (pw == NULL) {
                         struct passwd *pwd = getpwnam(*argv);                                  warnx("unknown user %s", idstr);
   
                         if (pwd == NULL) {  
                                 warnx("%s: unknown user", *argv);  
                                 continue;                                  continue;
                         }                          }
                         who = pwd->pw_uid;                          p->id = pw->pw_uid;
                 } else {                  } else {
                         who = strtol(*argv, &ep, 10);                          p->id = strtonum(idstr, 0, UINT_MAX, &errstr);
                         if (*ep != NULL || who < 0) {                          if (errstr) {
                                 warnx("%s: bad value", *argv);                                  warnx("%s is %s", idstr, errstr);
                                 continue;                                  continue;
                         }                          }
                 }                  }
                 errs += donice(which, (uid_t)who, (int)prio);                  p++;
         }          }
         exit(errs != 0);          if (!nflag)
                   usage();
           exit(renice(params, p));
 }  }
   
 int  static int
 donice(int which, uid_t who, int prio)  renice(struct renice_param *p, struct renice_param *end)
 {  {
         int oldprio;          int old, errors = 0;
   
         errno = 0, oldprio = getpriority(which, who);          for (; p < end; p++) {
         if (oldprio == -1 && errno) {                  errno = 0;
                 warn("getpriority: %d", who);                  old = getpriority(p->type, p->id);
                 return (1);                  if (errno) {
                           warn("getpriority: %d", p->id);
                           errors++;
                           continue;
                   }
                   if (setpriority(p->type, p->id, p->pri) == -1) {
                           warn("setpriority: %d", p->id);
                           errors++;
                           continue;
                   }
                   printf("%d: old priority %d, new priority %d\n",
                       p->id, old, p->pri);
         }          }
         if (setpriority(which, who, prio) < 0) {          return (errors);
                 warn("setpriority: %d", who);  
                 return (1);  
         }  
         printf("%d: old priority %d, new priority %d\n", who, oldprio, prio);  
         return (0);  
 }  }
   
 void  __dead void
 usage(void)  usage(void)
 {  {
         extern char *__progname;          fprintf(stderr, "usage: renice -n increment [[-g] pgrp ...] "
               "[[-p] pid ...] [[-u] user ...]\n");
         fprintf(stderr, "usage: %s priority [[-g] pgrp ...] [[-p] pid ...] "  
             "[[-u] user ...]\n", __progname);  
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.13