[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
nice - run a command with modified niceness
Lines of code: 222
Principal syscall: nice(), setpriority()
Support syscall: execvp()
Options: 4 (1 short, 3 long)
Descended from nice in Version 4 UNIX (late 1973)
Added to Coreutils in November 1992 [First version]
Number of revisions: 128 [Code Evolution]
perm_related_errno()
- Checks if an error is permissions related
die()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process terminationquote()
- Converts an input argument to a printable string
Setup
nice begins with a couple macro definitions:
GET_NICENESS()
- Function-like macro that returns the current nice valueNZERO
- the most favorable nice value (without sign)
main() initializes the following:
current_niceness
- The current niceness of the processadjustment
- The adjustment requested by the useradjustment_given
- The given adjustment input stringok
- The return status of the programi
- Generic iterator over arguments
Parsing
Two questions answered by parsing:
- What niceness adjustment should be applied?
- What program do we modify?
Parsing failures
These failure cases are explicitly checked:
- Nice value is too large
- An adjustment is provided, but not a command
All parsing failures result in a short error message followed by the usage instructions.
Extra comments
The parsing procedure uses both Getopt and checks an older syntax of only providing a number for backwards compatibility.
Execution
Despite the length of the utility, the common case only involves two lines of code (1, 2):
... ok = (nice (adjustment) != -1 || errno == 0); ... execvp (argv[i], &argv[i]); ...
The first changes the current nice value while the second executes the given command (cloning from the nice utility with the modified nice value). If control returns to the nice utility after calling execvp()
, that means execution failed and we need to handle an error.
The remaining lines of code provide for contingencies. Such as for newer systems that don't include a nice()
syscall, instead we use setpriority()
Exit Status
The nice utility is one of the few that specify more exit values than 0 (EXIT_SUCCESS) and 1 (EXIT_FAILURE). Instead, we also include:
EXIT_CANCELED
- The nice portion of execution failedEXIT_ENOENT
- The target command doesn't existEXIT_CANNOT_INVOKE
- The target command did not execute properly
Failure cases:
- We cannot retrieve the current niceness
- We cannot set the new niceness value (i.e. no perms for lower niceness)
All failures at this stage output an error message to STDERR and return without displaying usage help