aboutsummaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2020-02-18ash: jobs - Do not block when waiting on SIGCHLDDenys Vlasenko
Upstream comment: Date: Mon, 7 May 2018 00:40:34 +0800 jobs - Do not block when waiting on SIGCHLD Because of the nature of SIGCHLD, the process may have already been waited on and therefore we must be prepared for the case that wait may block. So ensure that it doesn't by using WNOHANG. Furthermore, multiple jobs may have exited when gotsigchld is set. Therefore we need to wait until there are no zombies left. Lastly, waitforjob needs to be called with interrupts off and the original patch broke that. Fixes: 03876c0743a5 ("eval: Reap zombies after built-in...") Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> While at it, removed INT_ON/OFF in waitforjob() - it must be called from INT_OFF region anyway. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-18ash: eval: Reap zombies after built-in commands and functionsDenys Vlasenko
Upstream commit: Date: Mon, 26 Mar 2018 23:55:50 +0800 eval: Reap zombies after built-in commands and functions Currently dash does not reap dead children after built-in commands or functions. This means that if you construct a loop consisting of solely built-in commands and functions, then zombies can hang around indefinitely. This patch fixes this by reaping when necessary after each built-in command and function. Reported-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: exec: Never rehash regular built-insDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:51 +0800 exec: Never rehash regular built-ins As regular (including special) built-ins can never be overridden, we should never remove them from the hash table. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: exec: Stricter pathopt parsingDenys Vlasenko
Upstream comment: Date: Sat, 19 May 2018 02:39:50 +0800 exec: Stricter pathopt parsing This patch changes the parsing of pathopt. First of all only %builtin and %func (with arbitrary suffixes) will be recognised. Any other pathopt will be treated as a normal directory. Furthermore, pathopt can now be specified before the directory, rather than after it. In fact, a future version may remove support for pathopt suffixes. Wherever the pathopt is placed, an optional % may be placed after it to terminate the pathopt. This is so that it is less likely that a genuine directory containing a % sign is parsed as a pathopt. Users of padvance outside of exec.c have also been modified: 1) cd(1) will always treat % characters as part of the path. 2) chkmail will continue to accept arbitrary pathopt. 3) find_dot_file will ignore the %builtin pathopt instead of trying to do a stat in the accompanying directory (which is usually the current directory). The patch also removes the clearcmdentry optimisation where we attempt to only partially flush the table where possible. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: exec: Do not allocate stack string in padvanceDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:48 +0800 exec: Do not allocate stack string in padvance Many callers of padvance immediately free the allocated string so this patch moves the stalloc call to the caller. Instead of returning the allocated string, padvance now returns the length to allocate (this may be longer than the actual string length, even including the NUL). For the case where we would previously return NULL, we now return -1. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: memalloc: Add growstackto helperDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:46 +0800 memalloc: Add growstackto helper This patch adds the growstackto helper which repeatedly calls growstackblock until the requested size is reached. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: parser: Save/restore here-documents in command substitutionDenys Vlasenko
Upstream comment: Date: Sat, 19 May 2018 02:39:42 +0800 parser: Save/restore here-documents in command substitution This patch changes the parsing of here-documents within command substitution, both old style and new style. In particular, the original here-document list is saved upon the beginning of parsing command substitution and restored when exiting. This means that here-documents outside of command substitution can no longer be filled by text within it and vice-versa. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: mkinit: Split reset into exitreset and resetDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:40 +0800 mkinit: Split reset into exitreset and reset Previously reset was called after exitshell. This was changed so that it was called before exitshell because certain state needed to be reset in order for the EXIT trap to work. However, this caused issues because certain other states (such as local variables) should not be reset. This patch fixes this by creating a new function exitreset that is called prior to exitshell and moving reset back to its original location. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: expand: Fix trailing newlines processing in backquote expandingDenys Vlasenko
Upstream commit: Date: Mon, 29 Apr 2019 19:13:37 +0500 expand: Fix trailing newlines processing in backquote expanding According to POSIX.1-2008 we should remove newlines only at the end of the substitution. Newlines-only substitions causes dash to remove newlines before beggining of the substitution. The following code: cat <<END 1 $(echo "") 2 END prints "1<newline>2" instead of expected "1<newline><newline>2". This patch fixes trailing newlines processing in backquote expanding. Signed-off-by: Nikolai Merinov <n.merinov@inango-systems.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-17ash: parser: Only accept single-digit parameter expansion outside of bracesDenys Vlasenko
Upstream commit: Date: Mon, 27 May 2019 13:39:37 +0800 parser: Only accept single-digit parameter expansion outside of braces This patch should fix the problem. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: shell: Fix clang warnings about "string plus integer"Denys Vlasenko
Upstream commit: Date: Sat, 15 Dec 2018 18:49:31 +0100 shell: Fix clang warnings about "string plus integer" Building with clang results in some warnings about integer values being added to strings. While the code itself is fine and the warnings are indeed harmless, fixing them also makes the semantic more explicit: what it is actually being increased is the address which points to the start of the string in order to skip the initial character when some conditions are met. Signed-off-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: eval: Use the correct expansion mode for fd redirectionDenys Vlasenko
Upstream comment: Date: Mon, 19 Nov 2018 18:00:32 +0800 eval: Use the correct expansion mode for fd redirection It has been reported that echo test >&$EMPTY_VARIABLE causes dash to segfault. This is a symptom of the bigger problem that dash tries to perform pathname expansion as well as field splitting on the word after >& and <&. This is wrong and this patch fixes it to use the same expansions as done on a normal redirection. Reported-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: expand: Fix skipping of command substitution when trimming in evalvarDenys Vlasenko
Upstream commit: Date: Mon, 28 May 2018 17:09:48 +0800 expand: Fix skipping of command substitution when trimming in evalvar When we are trimming an unset variable in evalvar, any embedded command substitution that should have been skipped are not. This can cause them to be evaluated later should there be other command substitutions in the same input word. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: main: Print \n upon EOF (CTRL-D) when run interactivelyDenys Vlasenko
Upstream comment: Date: Fri, 7 Sep 2018 10:34:14 +0200 main: Print \n upon EOF (CTRL-D) when run interactively Exiting dash via a ^D instead of with "exit" causes dash to forget to print a newline. sh-3.1$ sh sh-3.1$ ^D sh-3.1$ dash $ sh-3.1$ It is more neat and tidy to send a newline similarly to what bash does, so it doesn't make the next prompt of the parent shell look ugly. Suggested by jidanni. Signed-off-by: Gerrit Pape <pape@smarden.org> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> [reworded the patch description] Signed-off-by: Andrej Shadura <andrew.shadura@collabora.co.uk> Bug-Debian: http://bugs.debian.org/476422 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: expand: Use HOME in tilde expansion when it is emptyDenys Vlasenko
Upstream commit: Date: Sun, 27 May 2018 17:31:57 +0800 expand: Use HOME in tilde expansion when it is empty Currently if HOME is set to empty tilde expansion will fail, i.e., it will remain as a literal tilde. This patch changes it to return the empty string as required by POSIX. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: builtin: Mark more regular built-insDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:49 +0800 builtin: Mark more regular built-ins This patch marks the following built-ins as regular, meaning that they cannot be overriden using PATH search: hash pwd type ulimit Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: jobs: Replace some uses of fmtstr with stpcpy/stpncpyDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:45 +0800 jobs: Replace some uses of fmtstr with stpcpy/stpncpy Some uses of fmtstr, particularly the ones without a format string, can be replaced with stpcpy or stpncpy. This patch does that so we don't have to introduce unnecessary format strings in order to silence compiler warnings. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: output: Fix fmtstr return valueDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:44 +0800 output: Fix fmtstr return value The function fmtstr is meant to return the actual length of output produced, rather than the untruncated length. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: main: Only set savestatus in exitcmdDenys Vlasenko
Upstream commit: Date: Sat, 19 May 2018 02:39:38 +0800 main: Only set savestatus in exitcmd Currently exitcmd sets exitstatus and then savestatus if the latter was previously set. In fact, as exitcmd always raises an exception and will either end up in the setjmp call in main() or exitshell(), where exitstatus is always replaced by savestatus if set, we only need to set savestatus. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: [BUILTIN] Exit without arguments in a trap should use status outside trapsDenys Vlasenko
Upstream commit: Date: Mon Oct 6 10:39:47 2014 +0800 [BUILTIN] Exit without arguments in a trap should use status outside traps POSIX now requires that exit without arguments in a trap should return the last command status prior to executing traps. This patch implements this behaviour. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: parser: Fix incorrect eating of backslash newlinesDenys Vlasenko
Keeping up with upstream (in our case, 'before patch' code is not buggy). Upstream commit: Date: Fri, 11 May 2018 23:41:25 +0800 parser: Fix incorrect eating of backslash newlines With the introduction of synstack->syntax, a number of references to the syntax variable was missed during the conversion. This causes backslash newlines to be incorrectly removed in single quote context. This patch also combines these calls into a new helper function pgetc_top. Fixes: ab1cecb40478 ("parser: Add syntax stack for recursive...") Reported-by: Leah Neukirchen <leah@vuxu.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-16ash: use pgetc_eatbnl() in more places, take 2Denys Vlasenko
Adding previously skipped "readtoken1(pgetc_eatbnl(), DQSYNTAX..." changes from upstream commit: Date: Thu Mar 8 08:37:11 2018 +0100 Author: Harald van Dijk <harald@gigawatt.nl> parser: use pgetc_eatbnl() in more places dash has a pgetc_eatbnl function in parser.c which skips any backslash-newline combinations. It's not used everywhere it could be. There is also some duplicated backslash-newline handling elsewhere in parser.c. Replace most of the calls to pgetc() with calls to pgetc_eatbnl() and remove the duplicated backslash-newline handling. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-14fdisk: add HFS / HFS+ partition typeDenys Vlasenko
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-13tftp: on download, open local file only when first bit of data arrivedDenys Vlasenko
No reason to potentially clobber existing file before absolutely necessary. function old new delta tftp_protocol 1947 2020 +73 tftp_main 393 376 -17 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 73/-17) Total: 56 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-13tftp: fix thinko in code shrinkDenys Vlasenko
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-13tftp: code shrinkDenys Vlasenko
function old new delta tftp_protocol 1949 1947 -2 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-13tftpd: show requested file name in open error messageDenys Vlasenko
function old new delta tftp_protocol 1902 1949 +47 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-02-02awk: fix more "length" cases, closes 12486Denys Vlasenko
function old new delta next_token 808 831 +23 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-29ash,hush: allow builtins to be tab-completed, closes 7532Ron Yorston
function old new delta complete_cmd_dir_file 678 830 +152 get_builtin_name - 35 +35 optschanged 125 132 +7 hush_main 1069 1076 +7 save_command_ps_at_cur_history 76 78 +2 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/0 up/down: 203/0) Total: 203 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-29xargs: fix handling of quoted arguments, closes 11441Ron Yorston
As reported in bug 11441 when presented with a large number of quoted arguments xargs can return 'argument line too long': seq 10000 29999 | sed -e 's/^/"/' -e 's/$/"/' | busybox xargs echo This happens because the variant of process_stdin() which handles quoted arguments doesn't preserve state between calls. If the allowed number of characters is exceeded part way through a quoted argument the next call to process_stdin() incorrectly treats the terminating quote as a starting quote, thus quoting all of the argument separators. function old new delta process_stdin 274 303 +29 xargs_main 731 745 +14 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 43/0) Total: 43 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-29vi: fixes to string search in colon commands, closes 10321Ron Yorston
Handling of string searches in colon commands (e.g ':/pat1/,/pat2/cmd') differ from standard vi: - As reported in bug 10321 such searches can't be repeated using the 'n' command. This is because the last search pattern isn't updated. - The search also can't be repeated using the command '://' because an empty search pattern doesn't imply the use of the last search pattern. - Such searches should start on the line after the current line, otherwise '://' never moves to the next occurrence of the pattern. This can also affect other cases where line ranges are specified using search patterns. Fix these various issues. function old new delta get_one_address 325 342 +17 Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-29ash: improve expandstr()Ron Yorston
The dash maintainer recently posted a fix for issues with expanding PS1. These had already been fixed differently in BusyBox ash. Borrow a couple of improvements: - Use a single call to setjmp() to trap errors in both readtoken1() and expandarg(). - In case of error set the prompt to the literal value of PS1 rather than the half-digested nonsense in stackblock() which might include ugly control characters. function old new delta expandstr 353 300 -53 Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-29syslogd: add config option to include milliseconds in timestampsPeter Korsgaard
For some use cases, having logs with more than 1 second accuracy can be helpful. Add an option to include milliseconds when adding a timestamp in HH:MM:SS.mmm format, similar to syslog-ng with fraq_digits(3) or journalctl -o short-precise. For simplicity, abuse the remaining space in the buffer used by ctime to add the millieconds (overwriting year). function old new delta timestamp_and_log 401 448 +47 Signed-off-by: Peter Korsgaard <peter@korsgaard.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-01-14udhcpd: mangle hostnames starting with dash ("-option")Denys Vlasenko
function old new delta add_lease 316 328 +12 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-12-03whois: limit total length of response to 32+2 kbDenys Vlasenko
function old new delta query 517 554 +37 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-12-03init: improve handling of signals racing with each otherDenys Vlasenko
Before this change, a request to reboot could be "overwritten" by e.g. SIGHUP. function old new delta init_main 709 793 +84 packed_usage 33273 33337 +64 run_actions 109 117 +8 stop_handler 87 88 +1 check_delayed_sigs 340 335 -5 run 214 198 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/2 up/down: 157/-21) Total: 136 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-12-02init: if tcgetattr() fails, don't even try to tcsetattr()Denys Vlasenko
function old new delta set_sane_term 111 114 +3 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-28hush: fix preprocessor directives indentationDenys Vlasenko
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-27grep: add -RTomi Leppanen
This adds -R option to grep similar to GNU grep. It is the same as -r but also dereferences symbolic links to directories. function old new delta grep_main 834 850 +16 packed_usage 33362 33368 +6 grep_file 1440 1441 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 23/0) Total: 23 bytes Signed-off-by: Tomi Leppanen <tomi.leppanen@jolla.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-23bc: fix comparison bug, closes 12336Denys Vlasenko
function old new delta bc_num_cmp 249 259 +10 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-19Remove stime() function callsAlistair Francis
stime() has been deprecated in glibc 2.31 and replaced with clock_settime(). Let's replace the stime() function calls with clock_settime() in preperation. function old new delta rdate_main 197 224 +27 clock_settime - 27 +27 date_main 926 941 +15 stime 37 - -37 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 2/0 up/down: 69/-37) Total: 32 bytes Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-17Updated inittab example documentationDenys Vlasenko
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-17chgrp: correct the usage for non-desktop chgrp callsLiu, Shuang (ADITG/ESM)
When IF_DESKTOP is not defined, chown and chgrp only takes option -R -h, However the usage output of chgrp is wrong: $ ./busybox.nosuid chown Usage: chown [-Rh]... USER[:[GRP]] FILE... $ ./busybox.nosuid chgrp Usage: chgrp [-RhLHP]... GROUP FILE... $ ./busybox.nosuid chgrp -H group dummy chgrp: invalid option -- 'H' Usage: chgrp [-RhLHP]... GROUP FILE... The chgrp is now a wrapper of chown, so the recognized options shall be the same. This is introduced by 34425389e09353a8dacdd6b23a62553f699c544c I would expect the correct behavior shall be the same as chown. So suggest the below patch, the behavior shall be: $ ./busybox.nosuid chgrp Usage: chgrp [-Rh]... GROUP FILE... Signed-off-by: Shuang Liu <sliu@de.adit-jv.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-09taskset: tighten the check for stride valuesDenys Vlasenko
function old new delta taskset_main 986 987 +1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-09taskset: implement stride argumentDenys Vlasenko
function old new delta taskset_main 925 986 +61 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-08unxz: show -t in --helpDenys Vlasenko
function old new delta packed_usage 33236 33247 +11 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-08taskset: update commentDenys Vlasenko
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-01taskset: add support for taking/printing CPU list (-c option)Denys Vlasenko
function old new delta taskset_main 511 855 +344 Based on patch by Fryderyk Wrobel <frd1996@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-11-01hush: restore redirected stdinDenys Vlasenko
function old new delta restore_redirects 52 95 +43 save_fd_on_redirect 243 253 +10 hfopen 90 99 +9 fgetc_interactive 259 261 +2 builtin_type 117 115 -2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/1 up/down: 64/-2) Total: 62 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2019-10-30ntpd: decrease MIN_FREQHOLD by 2, increase "penalty" for largish offset x2Denys Vlasenko
> 2018-07-25: > ntpd: increase MIN_FREQHOLD by 3 > This means we'll start correcting frequency ~5 minutes after start, > not ~3.5 ones. > With previous settings I still often see largish ~0.7s initial offsets > only about 1/2 corrected before frequency correction kicks in, > resulting in ~200ppm "correction" which is then slowly undone. Review of real-world results of the above shows that with small initial offsets, freq correction can be allowed to kick in sooner, whereas with large (~0.8s) offsets, we still start freq correction a bit too soon. Let's rebalance this a bit. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>