Contents of /trunk/mkinitrd-magellan/busybox/libbb/copyfd.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 1942 byte(s)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 1942 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Utility routines. |
4 | * |
5 | * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ |
9 | |
10 | #include <errno.h> |
11 | #include <stdlib.h> |
12 | #include <string.h> |
13 | #include <unistd.h> |
14 | |
15 | #include "libbb.h" |
16 | |
17 | |
18 | #if BUFSIZ < 4096 |
19 | #undef BUFSIZ |
20 | #define BUFSIZ 4096 |
21 | #endif |
22 | |
23 | |
24 | static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) |
25 | { |
26 | int status = -1; |
27 | off_t total = 0; |
28 | RESERVE_CONFIG_BUFFER(buffer, BUFSIZ); |
29 | |
30 | if (src_fd < 0) goto out; |
31 | |
32 | if (!size) { |
33 | size = BUFSIZ; |
34 | status = 1; /* copy until eof */ |
35 | } |
36 | |
37 | while (1) { |
38 | ssize_t rd; |
39 | |
40 | rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); |
41 | |
42 | if (!rd) { /* eof - all done */ |
43 | status = 0; |
44 | break; |
45 | } |
46 | if (rd < 0) { |
47 | bb_perror_msg(bb_msg_read_error); |
48 | break; |
49 | } |
50 | /* dst_fd == -1 is a fake, else... */ |
51 | if (dst_fd >= 0) { |
52 | ssize_t wr = full_write(dst_fd, buffer, rd); |
53 | if (wr < rd) { |
54 | bb_perror_msg(bb_msg_write_error); |
55 | break; |
56 | } |
57 | } |
58 | total += rd; |
59 | if (status < 0) { /* if we aren't copying till EOF... */ |
60 | size -= rd; |
61 | if (!size) { |
62 | /* 'size' bytes copied - all done */ |
63 | status = 0; |
64 | break; |
65 | } |
66 | } |
67 | } |
68 | out: |
69 | RELEASE_CONFIG_BUFFER(buffer); |
70 | return status ? -1 : total; |
71 | } |
72 | |
73 | |
74 | #if 0 |
75 | void complain_copyfd_and_die(off_t sz) |
76 | { |
77 | if (sz != -1) |
78 | bb_error_msg_and_die("short read"); |
79 | /* if sz == -1, bb_copyfd_XX already complained */ |
80 | exit(xfunc_error_retval); |
81 | } |
82 | #endif |
83 | |
84 | off_t bb_copyfd_size(int fd1, int fd2, off_t size) |
85 | { |
86 | if (size) { |
87 | return bb_full_fd_action(fd1, fd2, size); |
88 | } |
89 | return 0; |
90 | } |
91 | |
92 | void bb_copyfd_exact_size(int fd1, int fd2, off_t size) |
93 | { |
94 | off_t sz = bb_copyfd_size(fd1, fd2, size); |
95 | if (sz == size) |
96 | return; |
97 | if (sz != -1) |
98 | bb_error_msg_and_die("short read"); |
99 | /* if sz == -1, bb_copyfd_XX already complained */ |
100 | exit(xfunc_error_retval); |
101 | } |
102 | |
103 | off_t bb_copyfd_eof(int fd1, int fd2) |
104 | { |
105 | return bb_full_fd_action(fd1, fd2, 0); |
106 | } |