Contents of /tags/mkinitrd-6_2_0/libbb/read.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/libbb/read.c
File MIME type: text/plain
File size: 2766 byte(s)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
Original Path: trunk/mkinitrd-magellan/busybox/libbb/read.c
File MIME type: text/plain
File size: 2766 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-2004 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 "libbb.h" |
11 | |
12 | ssize_t safe_read(int fd, void *buf, size_t count) |
13 | { |
14 | ssize_t n; |
15 | |
16 | do { |
17 | n = read(fd, buf, count); |
18 | } while (n < 0 && errno == EINTR); |
19 | |
20 | return n; |
21 | } |
22 | |
23 | /* |
24 | * Read all of the supplied buffer from a file. |
25 | * This does multiple reads as necessary. |
26 | * Returns the amount read, or -1 on an error. |
27 | * A short read is returned on an end of file. |
28 | */ |
29 | ssize_t full_read(int fd, void *buf, size_t len) |
30 | { |
31 | ssize_t cc; |
32 | ssize_t total; |
33 | |
34 | total = 0; |
35 | |
36 | while (len) { |
37 | cc = safe_read(fd, buf, len); |
38 | |
39 | if (cc < 0) |
40 | return cc; /* read() returns -1 on failure. */ |
41 | |
42 | if (cc == 0) |
43 | break; |
44 | |
45 | buf = ((char *)buf) + cc; |
46 | total += cc; |
47 | len -= cc; |
48 | } |
49 | |
50 | return total; |
51 | } |
52 | |
53 | // Die with an error message if we can't read the entire buffer. |
54 | void xread(int fd, void *buf, size_t count) |
55 | { |
56 | if (count) { |
57 | ssize_t size = full_read(fd, buf, count); |
58 | if (size != count) |
59 | bb_error_msg_and_die("short read"); |
60 | } |
61 | } |
62 | |
63 | // Die with an error message if we can't read one character. |
64 | unsigned char xread_char(int fd) |
65 | { |
66 | char tmp; |
67 | |
68 | xread(fd, &tmp, 1); |
69 | |
70 | return tmp; |
71 | } |
72 | |
73 | // Read one line a-la fgets. Works only on seekable streams |
74 | char *reads(int fd, char *buffer, size_t size) |
75 | { |
76 | char *p; |
77 | |
78 | if (size < 2) |
79 | return NULL; |
80 | size = full_read(fd, buffer, size-1); |
81 | if ((ssize_t)size <= 0) |
82 | return NULL; |
83 | |
84 | buffer[size] = '\0'; |
85 | p = strchr(buffer, '\n'); |
86 | if (p) { |
87 | off_t offset; |
88 | *p++ = '\0'; |
89 | // avoid incorrect (unsigned) widening |
90 | offset = (off_t)(p-buffer) - (off_t)size; |
91 | // set fd position right after '\n' |
92 | if (offset && lseek(fd, offset, SEEK_CUR) == (off_t)-1) |
93 | return NULL; |
94 | } |
95 | return buffer; |
96 | } |
97 | |
98 | ssize_t read_close(int fd, void *buf, size_t size) |
99 | { |
100 | int e; |
101 | size = full_read(fd, buf, size); |
102 | e = errno; |
103 | close(fd); |
104 | errno = e; |
105 | return size; |
106 | } |
107 | |
108 | ssize_t open_read_close(const char *filename, void *buf, size_t size) |
109 | { |
110 | int fd = open(filename, O_RDONLY); |
111 | if (fd < 0) |
112 | return fd; |
113 | return read_close(fd, buf, size); |
114 | } |
115 | |
116 | void *xmalloc_open_read_close(const char *filename, size_t *sizep) |
117 | { |
118 | char *buf; |
119 | size_t size = sizep ? *sizep : INT_MAX; |
120 | int fd = xopen(filename, O_RDONLY); |
121 | /* /proc/N/stat files report len 0 here */ |
122 | /* In order to make such files readable, we add small const */ |
123 | off_t len = xlseek(fd, 0, SEEK_END) + 256; |
124 | xlseek(fd, 0, SEEK_SET); |
125 | |
126 | if (len > size) |
127 | bb_error_msg_and_die("file '%s' is too big", filename); |
128 | size = len; |
129 | buf = xmalloc(size + 1); |
130 | size = read_close(fd, buf, size); |
131 | if ((ssize_t)size < 0) |
132 | bb_perror_msg_and_die("'%s'", filename); |
133 | xrealloc(buf, size + 1); |
134 | buf[size] = '\0'; |
135 | if (sizep) *sizep = size; |
136 | return buf; |
137 | } |