diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-05-05 18:39:22 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-05-05 18:39:22 +0200 |
commit | c5d16e92c16cdd5ee57101e1ce88b5855e8ece6c (patch) | |
tree | 5ace6fd1189eebba1c54242214e2b0998c5716f8 | |
parent | 0cc9b1843df8c4b6838446542b3f7d5780fb9e84 (diff) | |
download | busybox-c5d16e92c16cdd5ee57101e1ce88b5855e8ece6c.tar.gz |
diff: fix -N and nonexistent files. Closes 7454
function old new delta
diffreg 1253 1310 +57
diff_main 1329 1355 +26
create_J 1819 1821 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 85/0) Total: 85 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/diff.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/editors/diff.c b/editors/diff.c index 3304edb26..7687518f3 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -715,9 +715,19 @@ static int diffreg(char *file[2]) fp[0] = stdin; fp[1] = stdin; for (i = 0; i < 2; i++) { - int fd = open_or_warn_stdin(file[i]); - if (fd == -1) - goto out; + int fd = STDIN_FILENO; + if (!LONE_DASH(file[i])) { + if (!(option_mask32 & FLAG(N))) { + fd = open_or_warn(file[i], O_RDONLY); + if (fd == -1) + goto out; + } else { + /* -N: if some file does not exist compare it like empty */ + fd = open(file[i], O_RDONLY); + if (fd == -1) + fd = xopen("/dev/null", O_RDONLY); + } + } /* Our diff implementation is using seek. * When we meet non-seekable file, we must make a temp copy. */ @@ -978,17 +988,23 @@ int diff_main(int argc UNUSED_PARAM, char **argv) argv += optind; while (L_arg) label[!!label[0]] = llist_pop(&L_arg); + + /* Compat: "diff file name_which_doesnt_exist" exits with 2 */ xfunc_error_retval = 2; for (i = 0; i < 2; i++) { file[i] = argv[i]; - /* Compat: "diff file name_which_doesnt_exist" exits with 2 */ if (LONE_DASH(file[i])) { fstat(STDIN_FILENO, &stb[i]); gotstdin++; - } else + } else if (option_mask32 & FLAG(N)) { + if (stat(file[i], &stb[i])) + xstat("/dev/null", &stb[i]); + } else { xstat(file[i], &stb[i]); + } } xfunc_error_retval = 1; + if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode))) bb_error_msg_and_die("can't compare stdin to a directory"); |