616a8f31c5f4f386484196db637234d1e4643255
[platform/upstream/coreutils.git] / src / nice.c
1 /* nice -- run a program with modified scheduling priority
2    Copyright (C) 1990, 1991 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 /* David MacKenzie <djm@gnu.ai.mit.edu> */
19
20 #ifdef HAVE_CONFIG_H
21 #if defined (CONFIG_BROKETS)
22 /* We use <config.h> instead of "config.h" so that a compilation
23    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
24    (which it would do because it found this file in $srcdir).  */
25 #include <config.h>
26 #else
27 #include "config.h"
28 #endif
29 #endif
30
31 #include <stdio.h>
32 #include <getopt.h>
33 #include <sys/types.h>
34 #ifndef NICE_PRIORITY
35 #include <sys/time.h>
36 #include <sys/resource.h>
37 #endif
38
39 #include "version.h"
40 #include "system.h"
41
42 #ifdef NICE_PRIORITY
43 #define GET_PRIORITY() nice (0)
44 #else
45 #define GET_PRIORITY() getpriority (PRIO_PROCESS, 0)
46 #endif
47
48 void error ();
49
50 static int isinteger ();
51 static void usage ();
52
53 /* The name this program was run with. */
54 char *program_name;
55
56 /* If non-zero, display usage information and exit.  */
57 static int show_help;
58
59 /* If non-zero, print the version on standard output and exit.  */
60 static int show_version;
61
62 static struct option const longopts[] =
63 {
64   {"adjustment", required_argument, NULL, 'n'},
65   {"help", no_argument, &show_help, 1},
66   {"version", no_argument, &show_version, 1},
67   {NULL, 0, NULL, 0}
68 };
69
70 void
71 main (argc, argv)
72      int argc;
73      char **argv;
74 {
75   int current_priority;
76   int adjustment = 0;
77   int minusflag = 0;
78   int adjustment_given = 0;
79   int optc;
80
81   program_name = argv[0];
82
83   while ((optc = getopt_long (argc, argv, "+0123456789-n:", longopts,
84                               (int *) 0)) != EOF)
85     {
86       switch (optc)
87         {
88         case '?':
89           usage (1);
90
91         case 0:
92           break;
93           
94         case 'n':
95           if (!isinteger (optarg))
96             error (1, 0, "invalid priority `%s'", optarg);
97           adjustment = atoi (optarg);
98           adjustment_given = 1;
99           break;
100
101         case '-':
102           minusflag = 1;
103           break;
104
105         default:
106           adjustment = adjustment * 10 + optc - '0';
107           adjustment_given = 1;
108         }
109     }
110
111   if (show_version)
112     {
113       printf ("%s\n", version_string);
114       exit (0);
115     }
116
117   if (show_help)
118     usage (0);
119
120   if (minusflag)
121     adjustment = -adjustment;
122   if (!adjustment_given)
123     adjustment = 10;
124
125   if (optind == argc)
126     {
127       if (adjustment_given)
128         usage (1);
129       /* No command given; print the priority. */
130       errno = 0;
131       current_priority = GET_PRIORITY ();
132       if (current_priority == -1 && errno != 0)
133         error (1, errno, "cannot get priority");
134       printf ("%d\n", current_priority);
135       exit (0);
136     }
137
138 #ifndef NICE_PRIORITY
139   errno = 0;
140   current_priority = GET_PRIORITY ();
141   if (current_priority == -1 && errno != 0)
142     error (1, errno, "cannot get priority");
143   if (setpriority (PRIO_PROCESS, 0, current_priority + adjustment))
144 #else
145   if (nice (adjustment) == -1)
146 #endif
147     error (1, errno, "cannot set priority");
148
149   execvp (argv[optind], &argv[optind]);
150   error (errno == ENOENT ? 127 : 126, errno, "%s", argv[optind]);
151 }
152
153 /* Return nonzero if S represents a (possibly signed) decimal integer,
154    zero if not. */
155
156 static int
157 isinteger (s)
158      char *s;
159 {
160   if (*s == '-')
161     ++s;
162   if (*s == 0)
163     return 0;
164   while (*s)
165     {
166       if (*s < '0' || *s > '9')
167         return 0;
168       ++s;
169     }
170   return 1;
171 }
172
173 static void
174 usage (status)
175      int status;
176 {
177   fprintf (status == 0 ? stdout : stderr, "\
178 Usage: %s [OPTION]... [COMMAND [ARG]...]\n\
179 ",
180            program_name);
181
182   if (status != 0)
183     fprintf (stderr, "Try `%s --help' for more information.\n",
184              program_name);
185   else
186
187     printf ("\
188 \n\
189   -ADJUST                   increment priority by ADJUST first\n\
190   -n, --adjustment ADJUST   same as -ADJUST\n\
191       --help                display this help and exit\n\
192       --version             output version information and exit\n\
193 \n\
194 With no COMMAND, print the current scheduling priority.  ADJUST is 10\n\
195 by default.  Range goes from -20 (highest priority) to 19 (lowest).\n\
196 ");
197
198   exit (status);
199 }