mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 06:20:23 +02:00
Miscellaneous 'sendfile' fixes and improved tests.
* libguile/filesys.c (scm_sendfile): In Linux-style sendfile(2) code, if EINTR or EAGAIN occurs, set result to 1 (not 0) so that we actually keep going. In non-sendfile(2) code, deal gracefully with short reads due to EOF. * test-suite/tests/filesys.test ("sendfile"): Use 'let*' to guarantee the needed order of operations: write (test-file) and then read it. Add code to check the written data (not just the returned length) in all tests, including the cases that hit EOF prematurely.
This commit is contained in:
parent
eed0d26cc0
commit
7f3be1db99
2 changed files with 51 additions and 31 deletions
|
@ -1160,7 +1160,7 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
|
||||||
total += result;
|
total += result;
|
||||||
else if (result < 0 && (errno == EINTR || errno == EAGAIN))
|
else if (result < 0 && (errno == EINTR || errno == EAGAIN))
|
||||||
/* Keep going. */
|
/* Keep going. */
|
||||||
result = 0;
|
result = 1;
|
||||||
}
|
}
|
||||||
while (total < c_count && result > 0);
|
while (total < c_count && result > 0);
|
||||||
}
|
}
|
||||||
|
@ -1175,6 +1175,7 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
|
||||||
{
|
{
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
size_t left;
|
size_t left;
|
||||||
|
int reached_eof = 0;
|
||||||
|
|
||||||
if (!SCM_UNBNDP (offset))
|
if (!SCM_UNBNDP (offset))
|
||||||
{
|
{
|
||||||
|
@ -1187,22 +1188,27 @@ SCM_DEFINE (scm_sendfile, "sendfile", 3, 1, 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (total = 0, left = c_count; total < c_count; )
|
for (total = 0, left = c_count; total < c_count && !reached_eof; )
|
||||||
{
|
{
|
||||||
size_t asked, obtained;
|
size_t asked, obtained, written;
|
||||||
|
|
||||||
asked = SCM_MIN (sizeof buf, left);
|
asked = SCM_MIN (sizeof buf, left);
|
||||||
obtained = full_read (in_fd, buf, asked);
|
obtained = full_read (in_fd, buf, asked);
|
||||||
if (obtained < asked)
|
if (obtained < asked)
|
||||||
SCM_SYSERROR;
|
{
|
||||||
|
if (errno == 0)
|
||||||
|
reached_eof = 1;
|
||||||
|
else
|
||||||
|
SCM_SYSERROR;
|
||||||
|
}
|
||||||
|
|
||||||
left -= obtained;
|
left -= obtained;
|
||||||
|
|
||||||
obtained = full_write (out_fd, buf, asked);
|
written = full_write (out_fd, buf, obtained);
|
||||||
if (obtained < asked)
|
if (written < obtained)
|
||||||
SCM_SYSERROR;
|
SCM_SYSERROR;
|
||||||
|
|
||||||
total += obtained;
|
total += written;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,38 +135,52 @@
|
||||||
(ref (call-with-input-file file get-bytevector-all)))
|
(ref (call-with-input-file file get-bytevector-all)))
|
||||||
|
|
||||||
(pass-if-equal "file" (cons len ref)
|
(pass-if-equal "file" (cons len ref)
|
||||||
(cons (call-with-input-file file
|
(let* ((result (call-with-input-file file
|
||||||
(lambda (input)
|
(lambda (input)
|
||||||
(call-with-output-file (test-file)
|
(call-with-output-file (test-file)
|
||||||
(lambda (output)
|
(lambda (output)
|
||||||
(sendfile output input len 0)))))
|
(sendfile output input len 0))))))
|
||||||
(call-with-input-file (test-file) get-bytevector-all)))
|
(out (call-with-input-file (test-file) get-bytevector-all)))
|
||||||
|
(cons result out)))
|
||||||
|
|
||||||
(pass-if-equal "file with offset"
|
(pass-if-equal "file with offset"
|
||||||
(cons (- len 777) (call-with-input-file file
|
(cons (- len 777) (call-with-input-file file
|
||||||
(lambda (input)
|
(lambda (input)
|
||||||
(seek input 777 SEEK_SET)
|
(seek input 777 SEEK_SET)
|
||||||
(get-bytevector-all input))))
|
(get-bytevector-all input))))
|
||||||
(cons (call-with-input-file file
|
(let* ((result (call-with-input-file file
|
||||||
(lambda (input)
|
(lambda (input)
|
||||||
(call-with-output-file (test-file)
|
(call-with-output-file (test-file)
|
||||||
(lambda (output)
|
(lambda (output)
|
||||||
(sendfile output input (- len 777) 777)))))
|
(sendfile output input (- len 777) 777))))))
|
||||||
(call-with-input-file (test-file) get-bytevector-all)))
|
(out (call-with-input-file (test-file) get-bytevector-all)))
|
||||||
|
(cons result out)))
|
||||||
|
|
||||||
(pass-if-equal "file with offset past the end" (- len 777)
|
(pass-if-equal "file with offset past the end"
|
||||||
(call-with-input-file file
|
(cons (- len 777) (call-with-input-file file
|
||||||
(lambda (input)
|
(lambda (input)
|
||||||
(call-with-output-file (test-file)
|
(seek input 777 SEEK_SET)
|
||||||
(lambda (output)
|
(get-bytevector-all input))))
|
||||||
(sendfile output input len 777))))))
|
(let* ((result (call-with-input-file file
|
||||||
|
(lambda (input)
|
||||||
|
(call-with-output-file (test-file)
|
||||||
|
(lambda (output)
|
||||||
|
(sendfile output input len 777))))))
|
||||||
|
(out (call-with-input-file (test-file) get-bytevector-all)))
|
||||||
|
(cons result out)))
|
||||||
|
|
||||||
(pass-if-equal "file with offset near the end" 77
|
(pass-if-equal "file with offset near the end"
|
||||||
(call-with-input-file file
|
(cons 77 (call-with-input-file file
|
||||||
(lambda (input)
|
(lambda (input)
|
||||||
(call-with-output-file (test-file)
|
(seek input (- len 77) SEEK_SET)
|
||||||
(lambda (output)
|
(get-bytevector-all input))))
|
||||||
(sendfile output input len (- len 77)))))))
|
(let* ((result (call-with-input-file file
|
||||||
|
(lambda (input)
|
||||||
|
(call-with-output-file (test-file)
|
||||||
|
(lambda (output)
|
||||||
|
(sendfile output input len (- len 77)))))))
|
||||||
|
(out (call-with-input-file (test-file) get-bytevector-all)))
|
||||||
|
(cons result out)))
|
||||||
|
|
||||||
(pass-if-equal "pipe" (cons len ref)
|
(pass-if-equal "pipe" (cons len ref)
|
||||||
(if (provided? 'threads)
|
(if (provided? 'threads)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue