--- Makefile | 1 + chgrp.1 | 2 +- nice.c | 74 +++++++++++++++++++++------------ renice.1 | 97 +++++++++++++++++++++++++++++++++++++++++++ renice.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util/estrtol.c | 9 ++-- 6 files changed, 278 insertions(+), 32 deletions(-) create mode 100644 renice.1 create mode 100644 renice.c diff --git a/Makefile b/Makefile index d90d690..b7d0fa7 100644 --- a/Makefile +++ b/Makefile _AT_@ -49,6 +49,7 @@ SRC = \ paste.c \ printenv.c \ pwd.c \ + renice.c \ rm.c \ rmdir.c \ sleep.c \ diff --git a/chgrp.1 b/chgrp.1 index 7196080..07a33a6 100644 --- a/chgrp.1 +++ b/chgrp.1 _AT_@ -1,6 +1,6 @@ .TH CHGRP 1 sbase\-VERSION .SH NAME -nice \- invoke a utility with an altered nice value +chgrp \- change the file group ownership .SH SYNOPSIS .B chgrp .RB [ \-R ] diff --git a/nice.c b/nice.c index dcbb05f..773f11b 100644 --- a/nice.c +++ b/nice.c _AT_@ -1,38 +1,58 @@ /* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <limits.h> #include <unistd.h> #include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <string.h> #include "util.h" -static void -usage(void) -{ - eprintf("usage: nice [-n inc] command [options ...]\n"); -} +#ifndef NZERO +/* limits.h could omit NZERO, but sane systems have it */ +#define NZERO 20 +#endif + +static void eusage(void); int main(int argc, char **argv) { - int inc = 10; - - ARGBEGIN { - case 'n': - inc = atoi(EARGF(usage())); - break; - default: - usage(); - } ARGEND; - - nice(inc); /* POSIX specifies the nice failure still invokes the command. */ - - if(!*argv) - usage(); - - execvp(*argv, argv); - eprintf("nice: '%s': %s\n", *argv, strerror(errno)); - - return EXIT_FAILURE; + const char *adj = "10"; + long val; + int c; + + while((c = getopt(argc, argv, "n:")) != -1) + switch(c) { + case 'n': + adj = optarg; + break; + case '?': + default: + eusage(); + break; + } + + argc -= optind; + argv += optind; + if(argc == 0) + eusage(); + + /* clamp the value to a meaningful range */ + val = estrtol(adj, 10); + val = MAX(1 - NZERO * 2, MIN(val, NZERO * 2 - 1)); + + errno = 0; + nice((int)val); + if(errno != 0) + perror("can't adjust niceness"); + + /* POSIX specifies the nice failure still invokes the command */ + execvp(argv[0], argv); + /* reached only on failure */ + perror(argv[0]); + return (errno == ENOENT)? 127 : 126; } +static void +eusage(void) +{ + eprintf("usage: nice [-n inc] command [options ...]\n"); +} diff --git a/renice.1 b/renice.1 new file mode 100644 index 0000000..1a46e4c --- /dev/null +++ b/renice.1 _AT_@ -0,0 +1,97 @@ +.TH PASTE 1 renice-VERSION "Jun 2013" +.SH NAME +renice \- set nice values of running processes +.SH "SYNOPSIS" +.PP +.B renice +.B \-n +.I increment +[ +.B \-g +| +.B \-p +| +.B \-u +] +.I ID... +.SH DESCRIPTION +The +.B renice +utility requests that the nice values of one or more +running processes be changed. By default, the applicable processes +are specified by their process IDs. When a process group is specified +(see +.B -g +), the request applies to all processes in the process group. If the +requested increment would raise or lower the nice value of the +executed utility beyond its limits, then the limit whose value was +exceeded is used. When a user is reniced, the request applies to all +processes whose saved set-user-ID matches the user ID corresponding to +the user. Regardless of which options are supplied or any other factor, +renice does not alter the nice values of any process unless the user +requesting such a change has appropriate privileges to do so for the +specified process. If the user lacks appropriate privileges to perform +the requested action, the utility returns an error status. +The saved set-user-ID of the user's process is checked instead of its +effective user ID when renice attempts to determine the user ID of the +process in order to determine whether the user has appropriate privileges. +.SH OPTIONS +.TP +.B \-g +interpret all operands as unsigned decimal integer process group IDs. +.TP +.B \-n +.I increment +specify how the nice value of the specified process or processes +is to be adjusted. The increment option-argument is a positive or +negative decimal integer used to modify the nice value of the +specified process or processes. positive increment values cause a +lower nice value. Negative increment values may require appropriate +privileges and cause a higher nice value. +.TP +.B \-p +interpret all operands as unsigned decimal integer process IDs. +The +.B \-p +option is the default if no options are specified. +.TP +.B \-u +interpret all operands as users. If a user exists with a user name +equal to the operand, then the user ID of that user is used in further +processing. Otherwise, if the operand represents an unsigned decimal +integer, used as the numeric user ID of the user. +.SH EXIT VALUES +On successful completion 0 is returned, a value which is >0 is +returned on error. +.SH FILES +.TP +.I /etc/passwd +used to map user names to user ID's. +.SH CONFORMING TO +The +.B renice +utility is IEEE Std 1003.1-2001 (POSIX.1) compatible. +.SH EXAMPLES +.TP +.I "renice -n 5 -p 987 32" +.PP +Adjust the nice value so that process IDs 987 and 32 would have a +lower nice value. +.TP +.I "renice -n -4 -g 324 76" +.PP +Adjust the nice value so that group IDs 324 and 76 would have a +higher nice value, if the user has the appropriate privileges to do so. +.TP +.I "renice -n 4 -u 8 sas" +.PP +Adjust the nice value so that numeric user ID 8 and user sas would +have a lower nice value. +Useful nice value increments on historical systems include +19 or 20 (the affected processes run only when nothing else in the +system attempts to run) and any negative number +(to make processes run faster). +.SH AUTHOR +Written by Lorenzo Cogotti. +.SH SEE ALSO +.BR nice(1) diff --git a/renice.c b/renice.c new file mode 100644 index 0000000..aed8fbc --- /dev/null +++ b/renice.c _AT_@ -0,0 +1,127 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <limits.h> +#include <pwd.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <sys/resource.h> +#include <unistd.h> +#include "util.h" + +#ifndef NZERO +/* limits.h could omit NZERO, but sane systems have it */ +#define NZERO 20 +#endif + +static int strtop(const char *); +static bool renice(int, int, int); +static void eusage(void); + +int +main(int argc, char **argv) +{ + const char *adj = "10"; + long val; + int i, c, which = PRIO_PROCESS, status = 0; + + while((c = getopt(argc, argv, "n:gpu")) != -1) + switch(c) { + case 'n': + adj = optarg; + break; + case 'g': + which = PRIO_PGRP; + break; + case 'p': + which = PRIO_PROCESS; + break; + case 'u': + which = PRIO_USER; + break; + case '?': + default: + eusage(); + break; + } + + argc -= optind; + argv += optind; + if(argc == 0) + eusage(); + + /* clamp value to a meaningful range */ + val = estrtol(adj, 10); + val = MAX(1 - NZERO * 2, MIN(val, NZERO * 2 - 1)); + for(i = 0; i < argc; i++) { + int who = -1; + + if(which == PRIO_USER) { + const struct passwd *pwd; + + errno = 0; + do pwd = getpwnam(argv[i]); while(errno == EINTR); + + if(pwd) + who = pwd->pw_uid; + else if(errno != 0) { + perror("can't read passwd"); + status = 1; + continue; + } + } + if(who < 0) + who = strtop(argv[i]); + + if(who < 0 || !renice(which, who, (int)val)) + status = 1; + } + + return status; +} + +static int +strtop(const char *s) +{ + char *end; + long n; + + errno = 0; + n = strtol(s, &end, 10); + if(*end != '\0') { + fprintf(stderr, "%s: not an integer\n", s); + return -1; + } + if(errno != 0 || n <= 0 || n > INT_MAX) { + fprintf(stderr, "%s: invalid value\n", s); + return -1; + } + + return (int)n; +} + +static bool +renice(int which, int who, int adj) +{ + errno = 0; + adj += getpriority(which, who); + if (errno != 0) { + fprintf(stderr, "can't get %d nice level: %s\n", who, strerror(errno)); + return false; + } + + adj = MAX(PRIO_MIN, MIN(adj, PRIO_MAX)); + if(setpriority(which, who, adj) == -1) { + fprintf(stderr, "can't set %d nice level: %s\n", who, strerror(errno)); + return false; + } + + return true; +} + +static void +eusage(void) +{ + eprintf("renice -n increment [-g | -p | -u] ID ...\n"); +} diff --git a/util/estrtol.c b/util/estrtol.c index d481445..ac37b8c 100644 --- a/util/estrtol.c +++ b/util/estrtol.c _AT_@ -13,13 +13,14 @@ estrtol(const char *s, int base) errno = 0; n = strtol(s, &end, base); - if(*end != '\0' || errno != 0) { - if(base == 0) { + if(*end != '\0') { + if(base == 0) eprintf("%s: not an integer\n", s); - } else { + else eprintf("%s: not a base %d integer\n", s, base); - } } + if(errno != 0) + eprintf("%s:", s); return n; } -- 1.8.2Received on Sun Jun 09 2013 - 17:39:47 CEST
This archive was generated by hypermail 2.3.0 : Sun Jun 09 2013 - 17:48:05 CEST