aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-05-05 18:39:22 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-05-05 18:39:22 +0200
commitc5d16e92c16cdd5ee57101e1ce88b5855e8ece6c (patch)
tree5ace6fd1189eebba1c54242214e2b0998c5716f8
parent0cc9b1843df8c4b6838446542b3f7d5780fb9e84 (diff)
downloadbusybox-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.c26
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");