[bug] printing zero size files

walter harms wharms at bfs.de
Mon Feb 20 18:08:00 UTC 2012



Am 20.02.2012 18:46, schrieb walter harms:
> 
> 
> Am 19.02.2012 17:35, schrieb Denys Vlasenko:
>> On Thursday 16 February 2012 17:21, walter harms wrote:
>>> Hi,
>>> i just found a minor but in lpr. (tested with 19.0)
>>>
>>>  touch null
>>>  lpr null <- never returns
>>
>> Can't reproduce.
>>
>> Please strace it.
>>
> 
> Hello Denis,
> can you reproduce it using  "lpr -Plp at remote null" ?
> 
> from strace:
> ...
> read(3, "\0", 1)                        = 1
> write(3, "\0", 1)                       = 1
> read(3, 0x7ffff39a19b0, 1)              = ? ERESTARTSYS (To be restarted)   <!-- last before SIGINT ->
> 



When i add a file size check it seems to work.

the problem is located here:
static void get_response_or_say_and_die(int fd, const char *errmsg)
{
	ssize_t sz;
	char buf[128];

	buf[0] = ' ';
	sz = safe_read(fd, buf, 1);  <-- never returns

i do not know the lpr specs but i guess a file size of 0 is not permitted.
(how to print a 0 byte file ?), causing the lpd never to answer.
this will fix the problem but i have done no other checks so it may have consequences
i am not aware of.

it would be nice if someone would check this fix.

re,
 wh

--- lpr.c.org   2012-02-20 18:59:56.000000000 +0100
+++ lpr.c       2012-02-20 18:57:24.000000000 +0100
@@ -243,15 +243,17 @@
                        bb_error_msg("sending data file");
                st.st_size = 0; /* paranoia: fstat may theoretically fail */
                fstat(dfd, &st);
-               fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename);
-               get_response_or_say_and_die(fd, "sending data file");
-               if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) {
-                       // We're screwed. We sent less bytes than we advertised.
-                       bb_error_msg_and_die("local file changed size?!");
-               }
-               write(fd, "", 1); // send ACK
-               get_response_or_say_and_die(fd, "sending data file");

+               if (st.st_size > 0) {
+                       fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename);
+                       get_response_or_say_and_die(fd, "sending data file");
+                       if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) {
+                               // We're screwed. We sent less bytes than we advertised.
+                               bb_error_msg_and_die("local file changed size?!");
+                       }
+                       write(fd, "", 1); // send ACK
+                       get_response_or_say_and_die(fd, "sending data file");
+               }
                // delete temporary file if we dumped stdin
                if (*argv == (char*)bb_msg_standard_input)
                        unlink(tempfile);












More information about the busybox mailing list