Bug 7784

Summary: diff applet fails to compare stdin and empty file
Product: Busybox Reporter: Roman Ekjanov <rekjanov>
Component: Standard ComplianceAssignee: unassigned
Status: RESOLVED FIXED    
Severity: minor CC: busybox-cvs
Priority: P5    
Version: 1.21.x   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Host: Target:
Build:

Description Roman Ekjanov 2015-01-07 17:20:59 UTC
#touch empty_file
#echo something | busybox diff empty_file -

expected (diff -u from diffutils):

--- empty_file  2015-01-07 11:59:45.196702422 -0500
+++ -   2015-01-07 11:59:52.310080775 -0500
@@ -0,0 +1 @@
+something

and diff returns 1 (files differ)

actual result with busybox's diff:
no output and diff returns 0 (files are same)

This is because diffreg function copies stdin into a temporary file and leaves the file pointer at the end of that file, so both i and j are 0 after first read, i is 0 because the file is empty and j is 0 because the file is EOF

i = fread(buf0, 1, sz, fp[0]);
j = fread(buf1, 1, sz, fp[1]);

As a result, the files are deemed same.

A lseek on fd_tmp or fseek on fp[1] after fdopen should fix this.

BTW, the man page for fopen/fdopen is a bit misleading as one can assume that fdopen with "r" would rewind the file, but the opengroup documentation for fdopen explicitely says:
The file position indicator associated with the new stream is set to the position indicated by the file offset associated with the file descriptor.

http://pubs.opengroup.org/onlinepubs/7908799/xsh/fdopen.html
Comment 1 Roman Ekjanov 2015-01-07 17:27:30 UTC
Sorry about the man page being misleading, I just noticed that it has the same desription about fdopen and file position.
Comment 2 Denys Vlasenko 2015-01-11 15:42:43 UTC
Good catch.
Fixed in git, thanks!