From c5d16e92c16cdd5ee57101e1ce88b5855e8ece6c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 5 May 2017 18:39:22 +0200 Subject: 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 --- editors/diff.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'editors/diff.c') 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"); -- cgit v1.2.3