[git commit] diff: fix -N and nonexistent files. Closes 7454

Denys Vlasenko vda.linux at googlemail.com
Fri May 5 16:39:22 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=c5d16e92c16cdd5ee57101e1ce88b5855e8ece6c
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 editors/diff.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/editors/diff.c b/editors/diff.c
index 3304edb..7687518 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");
 


More information about the busybox-cvs mailing list