(root)/
util-linux-2.39/
sys-utils/
renice.c
       1  /*
       2   * Copyright (c) 1983, 1989, 1993
       3   *	The Regents of the University of California.  All rights reserved.
       4   *
       5   * Redistribution and use in source and binary forms, with or without
       6   * modification, are permitted provided that the following conditions
       7   * are met:
       8   * 1. Redistributions of source code must retain the above copyright
       9   *    notice, this list of conditions and the following disclaimer.
      10   * 2. Redistributions in binary form must reproduce the above copyright
      11   *    notice, this list of conditions and the following disclaimer in the
      12   *    documentation and/or other materials provided with the distribution.
      13   * 3. All advertising materials mentioning features or use of this software
      14   *    must display the following acknowledgement:
      15   *	This product includes software developed by the University of
      16   *	California, Berkeley and its contributors.
      17   * 4. Neither the name of the University nor the names of its contributors
      18   *    may be used to endorse or promote products derived from this software
      19   *    without specific prior written permission.
      20   *
      21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31   * SUCH DAMAGE.
      32   */
      33  
      34   /* 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
      35    * - added Native Language Support
      36    */
      37  
      38  #include <sys/types.h>
      39  #include <sys/time.h>
      40  #include <sys/resource.h>
      41  
      42  #include <stdio.h>
      43  #include <pwd.h>
      44  #include <stdlib.h>
      45  #include <string.h>
      46  #include <errno.h>
      47  #include "nls.h"
      48  #include "c.h"
      49  #include "closestream.h"
      50  
      51  static const char *idtype[] = {
      52  	[PRIO_PROCESS]	= N_("process ID"),
      53  	[PRIO_PGRP]	= N_("process group ID"),
      54  	[PRIO_USER]	= N_("user ID"),
      55  };
      56  
      57  static void __attribute__((__noreturn__)) usage(void)
      58  {
      59  	FILE *out = stdout;
      60  	fputs(USAGE_HEADER, out);
      61  	fprintf(out,
      62  	      _(" %1$s [-n|--priority|--relative] <priority> [-p|--pid] <pid>...\n"
      63  		" %1$s [-n|--priority|--relative] <priority>  -g|--pgrp <pgid>...\n"
      64  		" %1$s [-n|--priority|--relative] <priority>  -u|--user <user>...\n"),
      65  		program_invocation_short_name);
      66  
      67  	fputs(USAGE_SEPARATOR, out);
      68  	fputs(_("Alter the priority of running processes.\n"), out);
      69  
      70  	fputs(USAGE_OPTIONS, out);
      71  	fputs(_(" -n <num>               specify the nice value\n"), out);
      72  	fputs(_("                          If POSIXLY_CORRECT flag is set in environment\n"), out);
      73  	fputs(_("                          then the priority is 'relative' to current\n"), out);
      74  	fputs(_("                          process priority. Otherwise it is 'absolute'.\n"), out);
      75  	fputs(_(" --priority <num>       specify the 'absolute' nice value\n"), out);
      76  	fputs(_(" --relative <num>       specify the 'relative' nice value\n"), out);
      77  	fputs(_(" -p, --pid              interpret arguments as process ID (default)\n"), out);
      78  	fputs(_(" -g, --pgrp             interpret arguments as process group ID\n"), out);
      79  	fputs(_(" -u, --user             interpret arguments as username or user ID\n"), out);
      80  	fputs(USAGE_SEPARATOR, out);
      81  	printf(USAGE_HELP_OPTIONS(24));
      82  	printf(USAGE_MAN_TAIL("renice(1)"));
      83  	exit(EXIT_SUCCESS);
      84  }
      85  
      86  static int getprio(const int which, const int who, int *prio)
      87  {
      88  	errno = 0;
      89  	*prio = getpriority(which, who);
      90  	if (*prio == -1 && errno) {
      91  		warn(_("failed to get priority for %d (%s)"), who, idtype[which]);
      92  		return -errno;
      93  	}
      94  	return 0;
      95  }
      96  
      97  static int donice(const int which, const int who, const int prio, const int relative)
      98  {
      99  	int oldprio, newprio;
     100  
     101  	if (getprio(which, who, &oldprio) != 0)
     102  		return 1;
     103  	
     104  	newprio = prio; // if not relative, set absolute priority
     105  
     106  	if (relative)
     107  		newprio = oldprio + prio;
     108  
     109  	if (setpriority(which, who, newprio) < 0) {
     110  		warn(_("failed to set priority for %d (%s)"), who, idtype[which]);
     111  		return 1;
     112  	}
     113  	if (getprio(which, who, &newprio) != 0)
     114  		return 1;
     115  	printf(_("%d (%s) old priority %d, new priority %d\n"),
     116  	       who, idtype[which], oldprio, newprio);
     117  	return 0;
     118  }
     119  
     120  /*
     121   * Change the priority (the nice value) of processes
     122   * or groups of processes which are already running.
     123   */
     124  int main(int argc, char **argv)
     125  {
     126  	int which = PRIO_PROCESS;
     127  	int who = 0, prio, errs = 0;
     128  	int relative = 0;
     129  	char *endptr = NULL;
     130  
     131  	setlocale(LC_ALL, "");
     132  	bindtextdomain(PACKAGE, LOCALEDIR);
     133  	textdomain(PACKAGE);
     134  	close_stdout_atexit();
     135  
     136  	argc--;
     137  	argv++;
     138  
     139  	if (argc == 1) {
     140  		if (strcmp(*argv, "-h") == 0 ||
     141  		    strcmp(*argv, "--help") == 0)
     142  			usage();
     143  
     144  		if (strcmp(*argv, "-v") == 0 ||
     145  		    strcmp(*argv, "-V") == 0 ||
     146  		    strcmp(*argv, "--version") == 0)
     147  			print_version(EXIT_SUCCESS);
     148  	}
     149  
     150  	if (*argv)
     151  	{
     152  		if (strcmp(*argv, "-n") == 0)
     153  		{
     154  			// Fully conform to posix only if POSIXLY_CORRECT is
     155  			// set in the environment. If not, use the absolute
     156  			// value as it's been used (incorrectly) since 2009
     157  			relative = getenv("POSIXLY_CORRECT") == NULL ? 0 : 1;
     158  			argc--;
     159  			argv++;
     160  		}
     161  		else if (strcmp(*argv, "--relative") == 0)
     162  		{
     163  			relative = 1;
     164  			argc--;
     165  			argv++;
     166  		}
     167  		else if (strcmp(*argv, "--priority") == 0) {
     168  			relative = 0;
     169  			argc--;
     170  			argv++;
     171  		}
     172  	}
     173  
     174  	if (argc < 2 || !*argv) {
     175  		warnx(_("not enough arguments"));
     176  		errtryhelp(EXIT_FAILURE);
     177  	}
     178  
     179  	prio = strtol(*argv, &endptr, 10);
     180  	if (*endptr) {
     181  		warnx(_("invalid priority '%s'"), *argv);
     182  		errtryhelp(EXIT_FAILURE);
     183  	}
     184  	argc--;
     185  	argv++;
     186  
     187  	for (; argc > 0; argc--, argv++) {
     188  		if (strcmp(*argv, "-g") == 0 || strcmp(*argv, "--pgrp") == 0) {
     189  			which = PRIO_PGRP;
     190  			continue;
     191  		}
     192  		if (strcmp(*argv, "-u") == 0 || strcmp(*argv, "--user") == 0) {
     193  			which = PRIO_USER;
     194  			continue;
     195  		}
     196  		if (strcmp(*argv, "-p") == 0 || strcmp(*argv, "--pid") == 0) {
     197  			which = PRIO_PROCESS;
     198  			continue;
     199  		}
     200  		if (which == PRIO_USER) {
     201  			struct passwd *pwd = getpwnam(*argv);
     202  
     203  			if (pwd != NULL)
     204  				who = pwd->pw_uid;
     205  			else
     206  				who = strtol(*argv, &endptr, 10);
     207  			if (who < 0 || *endptr) {
     208  				warnx(_("unknown user %s"), *argv);
     209  				errs = 1;
     210  				continue;
     211  			}
     212  		} else {
     213  			who = strtol(*argv, &endptr, 10);
     214  			if (who < 0 || *endptr) {
     215  				/* TRANSLATORS: The first %s is one of the above
     216  				 * three ID names. Read: "bad value for %s: %s" */
     217  				warnx(_("bad %s value: %s"), idtype[which], *argv);
     218  				errs = 1;
     219  				continue;
     220  			}
     221  		}
     222  		errs |= donice(which, who, prio, relative);
     223  	}
     224  	return errs != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
     225  }