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>
This commit is contained in:
Denys Vlasenko 2017-05-05 18:39:22 +02:00
parent 0cc9b1843d
commit c5d16e92c1

View File

@ -715,9 +715,19 @@ static int diffreg(char *file[2])
fp[0] = stdin; fp[0] = stdin;
fp[1] = stdin; fp[1] = stdin;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
int fd = open_or_warn_stdin(file[i]); int fd = STDIN_FILENO;
if (fd == -1) if (!LONE_DASH(file[i])) {
goto out; 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. /* Our diff implementation is using seek.
* When we meet non-seekable file, we must make a temp copy. * 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; argv += optind;
while (L_arg) while (L_arg)
label[!!label[0]] = llist_pop(&L_arg); label[!!label[0]] = llist_pop(&L_arg);
/* Compat: "diff file name_which_doesnt_exist" exits with 2 */
xfunc_error_retval = 2; xfunc_error_retval = 2;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
file[i] = argv[i]; file[i] = argv[i];
/* Compat: "diff file name_which_doesnt_exist" exits with 2 */
if (LONE_DASH(file[i])) { if (LONE_DASH(file[i])) {
fstat(STDIN_FILENO, &stb[i]); fstat(STDIN_FILENO, &stb[i]);
gotstdin++; 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]); xstat(file[i], &stb[i]);
}
} }
xfunc_error_retval = 1; xfunc_error_retval = 1;
if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode))) 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"); bb_error_msg_and_die("can't compare stdin to a directory");