aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-04-16 07:46:53 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2005-04-16 07:46:53 +0000
commit9d0d1a21d0896332a0fefa8afe84ce7fe83a793c (patch)
treed8d1ce99cf940c5aa82b9182d4c8e1c42339acca
parentb902160dfbc73de1ccf34a4e9ef6821909936f17 (diff)
downloadbusybox-w32-9d0d1a21d0896332a0fefa8afe84ce7fe83a793c.tar.gz
busybox-w32-9d0d1a21d0896332a0fefa8afe84ce7fe83a793c.tar.bz2
busybox-w32-9d0d1a21d0896332a0fefa8afe84ce7fe83a793c.zip
Rework to fix http://bugs.uclibc.org/view.php?id=107
git-svn-id: svn://busybox.net/trunk/busybox@10117 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--libbb/copyfd.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/libbb/copyfd.c b/libbb/copyfd.c
index bf0a390a3..baf99df51 100644
--- a/libbb/copyfd.c
+++ b/libbb/copyfd.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * Utility routines. 3 * Utility routines.
4 * 4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 5 * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
25#include <unistd.h> 25#include <unistd.h>
26 26
27#include "busybox.h" 27#include "busybox.h"
28#include "libbb.h"
28 29
29 30
30#if BUFSIZ < 4096 31#if BUFSIZ < 4096
@@ -33,46 +34,54 @@
33#endif 34#endif
34 35
35 36
36/* If size is 0 copy until EOF */ 37static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size2)
37static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size)
38{ 38{
39 size_t read_total = 0; 39 int status;
40 RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); 40 size_t xread, wrote, total, size = size2;
41 41
42 while ((size == 0) || (read_total < size)) { 42 if ((dst_fd < 0) || (src_fd < 0)) {
43 size_t read_try; 43 return -1;
44 ssize_t read_actual; 44 }
45 45
46 if ((size == 0) || (size - read_total > BUFSIZ)) { 46 if (size == 0) {
47 read_try = BUFSIZ; 47 /* If size is 0 copy until EOF */
48 } else { 48 size = ULONG_MAX;
49 read_try = size - read_total; 49 }
50 }
51 50
52 read_actual = safe_read(src_fd, buffer, read_try); 51 {
53 if (read_actual > 0) { 52 RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
54 if ((dst_fd >= 0) && (bb_full_write(dst_fd, buffer, (size_t) read_actual) != read_actual)) { 53 total = 0;
55 bb_perror_msg(bb_msg_write_error); /* match Read error below */ 54 wrote = 0;
55 status = -1;
56 while (total < size)
57 {
58 xread = BUFSIZ;
59 if (size < (wrote + BUFSIZ))
60 xread = size - wrote;
61 xread = bb_full_read(src_fd, buffer, xread);
62 if (xread > 0) {
63 wrote = bb_full_write(dst_fd, buffer, xread);
64 if (wrote < xread) {
65 bb_perror_msg(bb_msg_write_error);
66 break;
67 }
68 total += wrote;
69 } else if (xread < 0) {
70 bb_perror_msg(bb_msg_read_error);
71 break;
72 } else if (xread == 0) {
73 /* All done. */
74 status = 0;
56 break; 75 break;
57 } 76 }
58 } 77 }
59 else if (read_actual == 0) { 78 RELEASE_CONFIG_BUFFER(buffer);
60 if (size) {
61 bb_error_msg("Unable to read all data");
62 }
63 break;
64 } else {
65 /* read_actual < 0 */
66 bb_perror_msg("Read error");
67 break;
68 }
69
70 read_total += read_actual;
71 } 79 }
72 80
73 RELEASE_CONFIG_BUFFER(buffer); 81 if (status == 0 || wrote)
74 82 return wrote;
75 return(read_total); 83 /* Some sortof error occured */
84 return -1;
76} 85}
77 86
78 87