| 1 | .TH "mtimeout" 1 "5 June 2011" "Mark Wooding" "Toys" |
| 2 | .SH NAME |
| 3 | mtimeout \- run a program for at most a given amount of time |
| 4 | . |
| 5 | .SH SYNOPSIS |
| 6 | .B mtimeout |
| 7 | .RB [ \-K ] |
| 8 | .RB [ \-k |
| 9 | .IR time ] |
| 10 | .RB [ \-b |
| 11 | .IR time ] |
| 12 | .RB [ \-s |
| 13 | .IR signal ] |
| 14 | .br |
| 15 | \c |
| 16 | .I time |
| 17 | .I command |
| 18 | .RI [ arguments ...] |
| 19 | . |
| 20 | .SH DESCRIPTION |
| 21 | The |
| 22 | .B mtimeout |
| 23 | command runs a specified program for at most a given amount of |
| 24 | .IR time . |
| 25 | The |
| 26 | .I time |
| 27 | may be fractional (with a decimal point), and may be followed by a unit |
| 28 | suffix: |
| 29 | .RB ` s ' |
| 30 | for seconds, |
| 31 | .RB ` m ' |
| 32 | for minutes, |
| 33 | .RB ` h ' |
| 34 | for hours, and |
| 35 | .RB ` d ' |
| 36 | for days. |
| 37 | .PP |
| 38 | It works by running the given command as a separate process group. It |
| 39 | then waits either for the top-level process (only) to exit, or for the |
| 40 | timeout to expire, whichever happens first. If the process exits, then |
| 41 | .B mtimeout |
| 42 | exits too, setting its exit status to match. Any other processes which |
| 43 | may have been started are left unmolested. |
| 44 | .PP |
| 45 | On the other hand, if the timeout goes off, then |
| 46 | .B mtimeout |
| 47 | sends its child process group the specified signal, by default |
| 48 | .BR SIGTERM , |
| 49 | though you can choose a different one with the |
| 50 | .B \-s |
| 51 | option. It then waits an additional five seconds (configurable with |
| 52 | the |
| 53 | .B \-k |
| 54 | option). If the child still hasn't exited, it sends |
| 55 | .B SIGKILL |
| 56 | to the process group and waits a further five seconds (configurable |
| 57 | with the |
| 58 | .B \-b |
| 59 | option). If the child still hasn't exited in this time, then |
| 60 | .B mtimeout |
| 61 | gives up and exits. |
| 62 | .PP |
| 63 | The following command-line options are recognized. |
| 64 | .TP |
| 65 | .B \-h, \-\-help |
| 66 | Prints a reasonably full help message describing the arguments and |
| 67 | options to standard output, and exits successfully. |
| 68 | .TP |
| 69 | .B \-v, \-\-version |
| 70 | Prints the program's version number to standard output, and exits |
| 71 | successfully. |
| 72 | .TP |
| 73 | .B \-u, \-\-usage |
| 74 | Prints a brief usage summary to standard output, and exits successfully. |
| 75 | .TP |
| 76 | .BI "\-b, \-\-bored-after=" time |
| 77 | After sending |
| 78 | .B SIGKILL |
| 79 | (or, with |
| 80 | .BR \-K , |
| 81 | the original signal) |
| 82 | wait for |
| 83 | .I time |
| 84 | before giving up and declaring the child process undead. The default |
| 85 | wait is five seconds. The |
| 86 | .I time |
| 87 | may have a unit suffix. |
| 88 | .TP |
| 89 | .B "\-K, \-\-no-kill" |
| 90 | Don't send a |
| 91 | .B SIGKILL |
| 92 | to the process: just wait for a while (see the |
| 93 | .B \-b |
| 94 | option) after sending the original signal to see whether it actually |
| 95 | dies. |
| 96 | .TP |
| 97 | .B "\-k, \-\-kill-after=" time |
| 98 | After sending a signal, wait for |
| 99 | .I time |
| 100 | before sending |
| 101 | .BR SIGKILL . |
| 102 | The default wait is five seconds. The |
| 103 | .I time |
| 104 | may have a unit suffix. |
| 105 | This option has no effect if |
| 106 | .BR \-K |
| 107 | is set. |
| 108 | .TP |
| 109 | .BI "\-s, \-\-signal=" signal |
| 110 | Send |
| 111 | .I signal |
| 112 | to the child process if it takes too long. The default is to send |
| 113 | .BR SIGTERM . |
| 114 | A signal may be given numerically (e.g., 9 for |
| 115 | .BR SIGKILL ) |
| 116 | or by name (e.g., |
| 117 | .BR KILL ). |
| 118 | .PP |
| 119 | The |
| 120 | .B mtimeout |
| 121 | program sets its exit status as follows. |
| 122 | .TP |
| 123 | 0\(em127 |
| 124 | The child process ran to completion within the given time: |
| 125 | .BR mtimeout 's |
| 126 | exit status is the same as that of the child process. |
| 127 | .TP |
| 128 | 128 |
| 129 | The child process exited in a way which |
| 130 | .B mtimeout |
| 131 | could not interpret. |
| 132 | .TP |
| 133 | 129\(em250 |
| 134 | The child process was killed by a signal: the exit status is 128 higher |
| 135 | than the signal number. If |
| 136 | .B mtimeout |
| 137 | had to kill the child because it took too long, then its exit status |
| 138 | will be like this. |
| 139 | .TP |
| 140 | 251 |
| 141 | The child took too long and couldn't be killed: |
| 142 | .B mtimeout |
| 143 | gave up waiting. |
| 144 | .TP |
| 145 | 252 |
| 146 | The target program couldn't be started: an error message was written to |
| 147 | standard error. |
| 148 | .TP |
| 149 | 253 |
| 150 | The |
| 151 | .B mtimeout |
| 152 | program couldn't parse the arguments provided to it: an error message |
| 153 | was written to standard error. |
| 154 | .TP |
| 155 | 254 |
| 156 | A system call made by |
| 157 | .B mtimeout |
| 158 | failed unexpectedly: an error message was written to standard error. |
| 159 | .TP |
| 160 | 255 |
| 161 | Not used. |
| 162 | . |
| 163 | .SH BUGS |
| 164 | Because |
| 165 | .B mtimeout |
| 166 | works by running its child process in a separate process group, it |
| 167 | interacts oddly with interactive shells. If the child process group |
| 168 | attempts to do terminal I/O (particularly reading from a terminal) then |
| 169 | it may be sent signals to suspend it. This may or may not make matters |
| 170 | worse. |
| 171 | .PP |
| 172 | The |
| 173 | .B mtimeout |
| 174 | program makes an effort to propagate interesting signals to its child |
| 175 | process group. Currently, it propagates |
| 176 | .BR SIGTSTP , |
| 177 | .BR SIGCONT , |
| 178 | .BR SIGINT , |
| 179 | .BR SIGHUP , |
| 180 | and |
| 181 | .BR SIGQUIT . |
| 182 | This list is subject to change: I don't think I'm likely to remove any |
| 183 | of the current signals from it, but I might add some; or I might add an |
| 184 | option to control this list. |
| 185 | .PP |
| 186 | If you suspend |
| 187 | .B mtimeout |
| 188 | and its child process group, the timer continues running anyway. (I'm |
| 189 | not quite sure whether this is the right behaviour.) |
| 190 | .PP |
| 191 | Nested timeouts don't work in a useful way if the outer timeout expires |
| 192 | earlier than the inner one. Since |
| 193 | .B SIGTERM |
| 194 | isn't propagated (currently, at least), the inner |
| 195 | .B mtimeout |
| 196 | is killed by the outer one, and loses control of its child process |
| 197 | group. You could possibly work around this by sending |
| 198 | .B SIGQUIT |
| 199 | instead. |
| 200 | .PP |
| 201 | Perhaps it would be useful to allow configuration of the `panic' |
| 202 | timeouts after the initial timeout signal is sent. |
| 203 | . |
| 204 | .SH AUTHOR |
| 205 | Mark Wooding, <mdw@distorted.org.uk> |