Austin Group Defect Tracker

Aardvark Mark IV

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001586 [1003.1(2016/18)/Issue7+TC2] Shell and Utilities Editorial Enhancement Request 2022-05-14 22:07 2024-06-11 09:07
Reporter steffen View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Closed  
Name steffen
User Reference
Section Vol. 3: Shell and Utilities
Page Number
Line Number (Line or range of lines)
Interp Status ---
Final Accepted Text Note: 0006080
Summary 0001586: timeout - new utility: run a command with a time limit
Description As of today it is very complicated to reliably run a program from within
a sh(1)ell with a timeout, a sh(1)ell can only hardly kill a child after
a timeout without introducing a race, as shown in issue #1585.

All modern operating systems (to my knowledge) therefore ship
a timeout(1) command for some time, which can be used to reliably run
a program with a timeout set.
Desired Action Add the timeout utility.
Here is the current manual page as present on OpenBSD, taken from
FreeBSD, under 2-clause BSD license:

     timeout – run a command with a time limit

     timeout [-k time] [-s sig] [--foreground] [--preserve-status] duration
             command [args]

     The timeout utility executes command, with any args, and kills it if it
     is still running after the specified duration. If duration is 0, the
     timeout is disabled.

     The options are as follows:

     -k time
             Send a second signal, SIGKILL, if the command is still running
             time after the first signal was sent.


             Do not propagate the timeout signal to children processes.

             Always exit with the same status as command, even if the timeout
             was reached.

     duration and time may contain a decimal fraction. The value defaults to
     seconds unless a unit suffix is given.

     The supported unit suffixes are:

           s seconds
           m minutes
           h hours
           d days

     If the timeout was not reached or --preserve-status was set, the exit
     status of command is returned.

     If the timeout was reached and --preserve-status was not set, an exit
     status of 124 is returned.

     If command exited after receiving a signal, the exit status returned is
     the signal number plus 128.
Tags issue8
Attached Files

- Relationships
related to 0001594Closed App usage about exit code 127 is wrong 

-  Notes
geoffclare (manager)
2022-07-29 11:03
edited on: 2022-08-01 15:45

Suggested changes...

On page 3301 insert a new page for timeout:

timeout - execute a utility with a time limit

timeout [-fp] [-k time] [-s signal_name] duration
    utility [argument...]

The timeout utility shall execute the utility named by the utility operand, with arguments supplied as the argument operands (if any), in a child process. If the value of the duration operand is non-zero and the child process has not terminated after the specified time period, timeout shall send the signal specified by the -s option, or the SIGTERM signal if -s is not given.

If the -f option is specified, the signal shall be sent only to the child process. Otherwise, it is implementation defined which one of the following methods is used to signal additional processes:

  • The timeout utility ensures it is a process group leader before creating the child process which executes the utility, in which case it shall send the signal to its process group.

  • The timeout utility arranges for any descendents of the child process that are orphaned to have their parent process changed to the timeout utility, in which case the signal shall be sent to the child process and all of its descendents.

If the subsequent wait status of the child process shows that it was stopped by a signal, a SIGCONT signal shall also be sent in the same manner as the first signal; otherwise, a SIGCONT signal may be sent in the same manner.

If the -k option is specified, and the child process created to execute the utility still has not terminated after the time period specified by the time option-argument has elapsed since the first signal was sent, timeout shall send a SIGKILL signal in the same manner as the first signal. If timeout receives a signal and propagates it to the child process (see ASYNCHRONOUS EVENTS below), this shall be treated as the first signal.

The timeout utility shall conform to [xref to XBD 12.2].

The following options shall be supported:

Only time out the utility itself, not its descendents.
-k time
Send a SIGKILL signal if the child process created to execute the utility has not terminated after the time period specified by time has elapsed since the first signal was sent. The value of time shall be interpreted as specified for the duration operand (see OPERANDS below).
Always preserve (mimic) the wait status of the executed utility, even if the time limit was reached.
-s signal_name
Specify the signal to send when the time limit is reached, using one of the symbolic names defined in the <signal.h> header. Values of signal_name shall be recognized in a case-independent fashion, without the SIG prefix. By default, SIGTERM shall be sent.

The maximum amount of time to allow the utility to run, specified as a decimal number with an optional decimal fraction and an optional suffix, which can be:

s seconds

m minutes

h hours

d days

If a decimal fraction is present, the application shall ensure that it is separated from the units by a <period>. If no suffix is present, the value shall specify seconds.

If the value is zero, timeout shall not enforce a time limit.
The name of a utility that is to be executed. If the utility operand names any of the special built-in utilities in [xref to 2.14], the results are undefined.
Any string to be supplied as an argument when executing the utility named by the utility operand.

Not used.


The following environment variables shall affect the execution of timeout:

Provide a default value for the internationalization variables that are unset or null. (See [xref to XBD 8.2] for the precedence of internationalization variables used to determine the values of locale categories.)
If set to a non-empty string value, override the values of all the other internationalization variables.
Determine the locale for the interpretation of sequences of bytes of text data as characters (for example, single-byte as opposed to multi-byte characters in arguments).
Determine the locale that should be used to affect the format and contents of diagnostic messages written to standard error.
Determine the location of messages objects and message catalogs.[/XSI]
Determine the search path that is used to locate the utility to be executed. See [xref to XBD 8.3].

The default behavior specified in [xref to XCU 1.4] shall apply, except that:

  • The timeout utility shall ignore SIGTTIN and SIGTTOU signals.

  • The timeout utility may alter the disposition of SIGALRM if the inherited disposition was for it to be ignored.

  • If the signal specified with the -s option, or any signal whose default action is to terminate the process, is delivered to the timeout utility, then unless the signal is SIGKILL or SIGSTOP, the timeout utility shall immediately send the same signal to the process or processes to which it would send a signal when the time limit is reached. If the delivered signal is SIGALRM, timeout may behave as if the time limit had been reached instead of sending SIGALRM.

  • If the -f option is not specified, then if timeout sends a signal to its process group, it shall briefly change the disposition of that signal to ignored while it sends the signal, so that it does not receive the signal itself.

With the single exception of the signal specified with the -s option, or SIGTERM if -s is not used, all signal dispositions inherited by the utility specified by the utility operand shall be the same as the disposition that timeout inherited.

Not used.

The standard error shall be used only for diagnostic messages.



If the -p option is not specified and the time limit was reached:

  • If the -k option was not specified or the utility terminated before the time period specified by the time option-argument elapsed since the first signal was sent, the exit status shall be 124.

  • If the -k option was specified and the SIGKILL signal was sent, it is unspecified whether the exit status is 124 or the behavior is as if the -p option was specified.

Otherwise, if the executed utility terminated by exiting, the exit status of timeout shall be that of the utility; if the utility was terminated by a signal, timeout shall terminate itself with the same signal while ensuring that a core image is not created.

If an error occurs, the following exit values shall be returned:

125 An error other than the two described below occurred.

126 The utility specified by utility was found but could not be executed.

127 The utility specified by utility could not be found.


Unlike the kill utility, the -s option of timeout is not required to accept the symbolic name 0 to represent signal value zero.

When the value of duration is zero, timeout does not time out the utility, but it does still perform signal propagation (including to descendents of the utility if -f is not specified).

Regardless of locale, the <period> character (the decimal-point character of the POSIX locale) is the decimal-point character recognized in the duration operand and the time option-argument.

The command, env, nice, nohup, time, timeout, and xargs utilities have been specified to use exit code 127 if a utility to be invoked cannot be found so that applications can distinguish ``failure to find a utility'' from ``invoked utility exited with an error indication''. The value 127 was chosen because it is not commonly used for other meanings; most utilities use small values for ``normal error conditions'' and the values above 128 can be confused with termination due to receipt of a signal. The value 126 was chosen in a similar manner to indicate that the utility could be found, but not invoked. Some scripts produce meaningful error messages differentiating the 126 and 127 cases. The distinction between exit codes 126 and 127 is based on KornShell practice that uses 127 when all attempts to exec the utility fail with [ENOENT], and uses 126 when any attempt to exec the utility fails for any other reason. The timeout utility extends these special exit codes to 125 and 124, with the meanings described in EXIT STATUS. A timeout exit status below 124 can only result from passing through the exit status of the executed utility.


Some timeout implementations make themselves a process group leader (when -f is not used) in order to be able to send signals to descendents of the child process. However, using this method means that any descendents which change their process group do not receive the signal. To ensure all descendents receive the signal, some implementations instead make use of a feature whereby descendents that are orphaned have their parent process changed to the timeout utility--that is, timeout becomes their ``reaper''--together with the ability of a reaper to send a signal to all of its descendents.

Some historical timeout implementations exited with status 128+signal_number when the child process was terminated by a signal before the time limit was reached (or when -p was used). This is reasonable when timeout is invoked from a shell which sets $? to 128+signal_number, but not all shells do that. In particular, the Korn Shell sets $? to 256+signal_number and so an exit status of 128+signal_number from timeout would be misleading. In order to avoid any possible ambiguity, this standard requires that timeout mimics the wait status of the child process by terminating itself with the same signal. When it does this it needs to ensure that it does not create a core image, otherwise it could overwrite one created by the invoked utility.

The timeout utility ignores SIGTTIN and SIGTTOU so that if the utility it executes reads from or writes to the controlling terminal and this generates a SIGTTIN or SIGTTOU for the process group, timeout will not be stopped by the signal and can still time out the utility.

Some historical timeout implementations always set the disposition for SIGTTIN and SIGTTOU in the child process to default, even if these signals were inherited as ignored. This could result in processes being stopped unexpectedly. Likewise, they did not ensure that for signals they caught, the disposition inherited by the executed utility was the same as the disposition that was inherited by timeout. This meant that, for example, if timeout was used in a script that was run with nohup, the utility executed by timeout would unexpectedly not be protected from SIGHUP. This standard requires that all signal dispositions inherited by the utility specified by the utility operand are the same as the disposition that timeout inherited, with the single exception of the signal that timeout sends when the time limit is reached, which needs to be inherited as default in order for the timeout to take effect (without resorting to SIGKILL if -k is specified).

Some historical timeout implementations only propagated a subset of the signals whose default action is to terminate the process to the child process if one was delivered to the timeout utility. Propagating these signals is beneficial, as otherwise termination of the timeout utility by a signal results in the utility it executed being left running indefinitely (unless it also received the signal, for example a terminal-generated SIGINT). There is no reason to select a subset of these signals to be propagated, therefore this standard requires them all to be propagated (except SIGKILL, which cannot). In the event that a user wants to prevent the utility being timed out, sending timeout a SIGKILL can be used for this purpose.



XBD Chapter 8 (on page NNN), Section 12.2 (on page NNN), <signal.h>

First released in Issue 8.

On page 2598 line 84368 section command, and
page 2694 line 87948 section env, and
page 3028 line 100764 section nice, and
page 3041 line 101203 section nohup, and
page 3299 line 111054 section time, and
page 3450 line 116526 section xargs, change:
The command, env, nice, nohup, time, and xargs utilities
The command, env, nice, nohup, time, timeout, and xargs utilities

geoffclare (manager)
2022-09-20 10:48

The timeout utility has been added in the Issue8NewAPIs branch in gitlab based on Note: 0005920
geoffclare (manager)
2022-11-21 16:14

Make the changes from "Additional APIs for Issue 8, Part 2" (Austin/1273).

- Issue History
Date Modified Username Field Change
2022-05-14 22:07 steffen New Issue
2022-05-14 22:07 steffen Name => steffen
2022-05-14 22:07 steffen Section => Vol. 3: Shell and Utilities
2022-05-14 22:07 steffen Line Number => (Line or range of lines)
2022-07-29 11:03 geoffclare Note Added: 0005920
2022-07-29 11:07 geoffclare Relationship added related to 0001594
2022-07-29 11:09 geoffclare Note Edited: 0005920
2022-08-01 15:45 geoffclare Note Edited: 0005920
2022-09-20 10:48 geoffclare Note Added: 0005971
2022-11-21 16:14 geoffclare Note Added: 0006080
2022-11-21 16:16 geoffclare Interp Status => ---
2022-11-21 16:16 geoffclare Final Accepted Text => Note: 0006080
2022-11-21 16:16 geoffclare Status New => Resolved
2022-11-21 16:16 geoffclare Resolution Open => Accepted As Marked
2022-11-21 16:17 geoffclare Tag Attached: issue8
2022-11-24 10:12 geoffclare Status Resolved => Applied
2024-06-11 09:07 agadmin Status Applied => Closed

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker