diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-09 09:50:33 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-09 09:50:33 +0000 |
| commit | f62ab2d77455ca42e1300e72b70d06e8a16db53b (patch) | |
| tree | 7a5391066d647ecec698214773eee8504c7a041a /libbb | |
| parent | dbef1173b00f0877a63121c40bf607155ac1e9a7 (diff) | |
| download | busybox-w32-f62ab2d77455ca42e1300e72b70d06e8a16db53b.tar.gz busybox-w32-f62ab2d77455ca42e1300e72b70d06e8a16db53b.tar.bz2 busybox-w32-f62ab2d77455ca42e1300e72b70d06e8a16db53b.zip | |
libbb: use improved xmalloc_read() from modprobe-small
who: fix compile breakage on some systems
modprobe-small: improve Config help text wording
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/read.c | 132 |
1 files changed, 56 insertions, 76 deletions
diff --git a/libbb/read.c b/libbb/read.c index 405e216dc..e67bbfb7e 100644 --- a/libbb/read.c +++ b/libbb/read.c | |||
| @@ -106,7 +106,7 @@ ssize_t FAST_FUNC full_read(int fd, void *buf, size_t len) | |||
| 106 | return total; | 106 | return total; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | // Die with an error message if we can't read the entire buffer. | 109 | /* Die with an error message if we can't read the entire buffer. */ |
| 110 | void FAST_FUNC xread(int fd, void *buf, size_t count) | 110 | void FAST_FUNC xread(int fd, void *buf, size_t count) |
| 111 | { | 111 | { |
| 112 | if (count) { | 112 | if (count) { |
| @@ -116,7 +116,7 @@ void FAST_FUNC xread(int fd, void *buf, size_t count) | |||
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | // Die with an error message if we can't read one character. | 119 | /* Die with an error message if we can't read one character. */ |
| 120 | unsigned char FAST_FUNC xread_char(int fd) | 120 | unsigned char FAST_FUNC xread_char(int fd) |
| 121 | { | 121 | { |
| 122 | char tmp; | 122 | char tmp; |
| @@ -124,7 +124,7 @@ unsigned char FAST_FUNC xread_char(int fd) | |||
| 124 | return tmp; | 124 | return tmp; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | // Read one line a-la fgets. Works only on seekable streams | 127 | /* Read one line a-la fgets. Works only on seekable streams */ |
| 128 | char* FAST_FUNC reads(int fd, char *buffer, size_t size) | 128 | char* FAST_FUNC reads(int fd, char *buffer, size_t size) |
| 129 | { | 129 | { |
| 130 | char *p; | 130 | char *p; |
| @@ -140,9 +140,9 @@ char* FAST_FUNC reads(int fd, char *buffer, size_t size) | |||
| 140 | if (p) { | 140 | if (p) { |
| 141 | off_t offset; | 141 | off_t offset; |
| 142 | *p++ = '\0'; | 142 | *p++ = '\0'; |
| 143 | // avoid incorrect (unsigned) widening | 143 | /* avoid incorrect (unsigned) widening */ |
| 144 | offset = (off_t)(p - buffer) - (off_t)size; | 144 | offset = (off_t)(p - buffer) - (off_t)size; |
| 145 | // set fd position right after '\n' | 145 | /* set fd position right after '\n' */ |
| 146 | if (offset && lseek(fd, offset, SEEK_CUR) == (off_t)-1) | 146 | if (offset && lseek(fd, offset, SEEK_CUR) == (off_t)-1) |
| 147 | return NULL; | 147 | return NULL; |
| 148 | } | 148 | } |
| @@ -203,39 +203,52 @@ ssize_t FAST_FUNC open_read_close(const char *filename, void *buf, size_t size) | |||
| 203 | return read_close(fd, buf, size); | 203 | return read_close(fd, buf, size); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | |||
| 206 | // Read (potentially big) files in one go. File size is estimated | 207 | // Read (potentially big) files in one go. File size is estimated |
| 207 | // by stat. | 208 | // by stat. Extra '\0' byte is appended. |
| 208 | void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) | 209 | void* FAST_FUNC xmalloc_read(int fd, size_t *sizep) |
| 209 | { | 210 | { |
| 210 | char *buf; | 211 | char *buf; |
| 211 | size_t size; | 212 | size_t size, rd_size, total; |
| 212 | int fd; | 213 | off_t to_read; |
| 213 | off_t len; | ||
| 214 | struct stat st; | 214 | struct stat st; |
| 215 | 215 | ||
| 216 | fd = open(filename, O_RDONLY); | 216 | to_read = sizep ? *sizep : MAXINT(ssize_t); /* max to read */ |
| 217 | if (fd < 0) | ||
| 218 | return NULL; | ||
| 219 | 217 | ||
| 220 | st.st_size = 0; /* in case fstat fail, define to 0 */ | 218 | /* Estimate file size */ |
| 219 | st.st_size = 0; /* in case fstat fails, assume 0 */ | ||
| 221 | fstat(fd, &st); | 220 | fstat(fd, &st); |
| 222 | /* /proc/N/stat files report len 0 here */ | 221 | /* /proc/N/stat files report st_size 0 */ |
| 223 | /* In order to make such files readable, we add small const */ | 222 | /* In order to make such files readable, we add small const */ |
| 224 | len = st.st_size | 0x3ff; /* read only 1k on unseekable files */ | 223 | size = (st.st_size | 0x3ff) + 1; |
| 225 | size = sizep ? *sizep : INT_MAX; | 224 | |
| 226 | if (len < size) | 225 | total = 0; |
| 227 | size = len; | 226 | buf = NULL; |
| 228 | buf = xmalloc(size + 1); | 227 | while (1) { |
| 229 | size = read_close(fd, buf, size); | 228 | if (to_read < size) |
| 230 | if ((ssize_t)size < 0) { | 229 | size = to_read; |
| 231 | free(buf); | 230 | buf = xrealloc(buf, total + size + 1); |
| 232 | return NULL; | 231 | rd_size = full_read(fd, buf + total, size); |
| 232 | if ((ssize_t)rd_size < 0) { /* error */ | ||
| 233 | free(buf); | ||
| 234 | return NULL; | ||
| 235 | } | ||
| 236 | total += rd_size; | ||
| 237 | if (rd_size < size) /* EOF */ | ||
| 238 | break; | ||
| 239 | to_read -= rd_size; | ||
| 240 | if (to_read <= 0) | ||
| 241 | break; | ||
| 242 | /* grow by 1/8, but in [1k..64k] bounds */ | ||
| 243 | size = ((total / 8) | 0x3ff) + 1; | ||
| 244 | if (size > 64*1024) | ||
| 245 | size = 64*1024; | ||
| 233 | } | 246 | } |
| 234 | xrealloc(buf, size + 1); | 247 | xrealloc(buf, total + 1); |
| 235 | buf[size] = '\0'; | 248 | buf[total] = '\0'; |
| 236 | 249 | ||
| 237 | if (sizep) | 250 | if (sizep) |
| 238 | *sizep = size; | 251 | *sizep = total; |
| 239 | return buf; | 252 | return buf; |
| 240 | } | 253 | } |
| 241 | 254 | ||
| @@ -284,59 +297,26 @@ void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) | |||
| 284 | } | 297 | } |
| 285 | #endif | 298 | #endif |
| 286 | 299 | ||
| 287 | void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *sizep) | 300 | // Read (potentially big) files in one go. File size is estimated |
| 288 | { | 301 | // by stat. |
| 289 | void *buf = xmalloc_open_read_close(filename, sizep); | 302 | void* FAST_FUNC xmalloc_open_read_close(const char *filename, size_t *sizep) |
| 290 | if (!buf) | ||
| 291 | bb_perror_msg_and_die("can't read '%s'", filename); | ||
| 292 | return buf; | ||
| 293 | } | ||
| 294 | |||
| 295 | /* libbb candidate */ | ||
| 296 | #if 0 | ||
| 297 | static void *xmalloc_read(int fd, size_t *sizep) | ||
| 298 | { | 303 | { |
| 299 | char *buf; | 304 | char *buf; |
| 300 | size_t size, rd_size, total; | 305 | int fd; |
| 301 | off_t to_read; | ||
| 302 | struct stat st; | ||
| 303 | |||
| 304 | to_read = sizep ? *sizep : INT_MAX; /* max to read */ | ||
| 305 | 306 | ||
| 306 | /* Estimate file size */ | 307 | fd = open(filename, O_RDONLY); |
| 307 | st.st_size = 0; /* in case fstat fails, assume 0 */ | 308 | if (fd < 0) |
| 308 | fstat(fd, &st); | 309 | return NULL; |
| 309 | /* /proc/N/stat files report st_size 0 */ | ||
| 310 | /* In order to make such files readable, we add small const */ | ||
| 311 | size = (st.st_size | 0x3ff) + 1; | ||
| 312 | 310 | ||
| 313 | total = 0; | 311 | buf = xmalloc_read(fd, sizep); |
| 314 | buf = NULL; | 312 | close(fd); |
| 315 | while (1) { | 313 | return buf; |
| 316 | if (to_read < size) | 314 | } |
| 317 | size = to_read; | ||
| 318 | buf = xrealloc(buf, total + size + 1); | ||
| 319 | rd_size = full_read(fd, buf + total, size); | ||
| 320 | if ((ssize_t)rd_size < 0) { /* error */ | ||
| 321 | free(buf); | ||
| 322 | return NULL; | ||
| 323 | } | ||
| 324 | total += rd_size; | ||
| 325 | if (rd_size < size) /* EOF */ | ||
| 326 | break; | ||
| 327 | to_read -= rd_size; | ||
| 328 | if (to_read <= 0) | ||
| 329 | break; | ||
| 330 | /* grow by 1/8, but in [1k..64k] bounds */ | ||
| 331 | size = ((total / 8) | 0x3ff) + 1; | ||
| 332 | if (size > 64*1024) | ||
| 333 | size = 64*1024; | ||
| 334 | } | ||
| 335 | xrealloc(buf, total + 1); | ||
| 336 | buf[total] = '\0'; | ||
| 337 | 315 | ||
| 338 | if (sizep) | 316 | void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *sizep) |
| 339 | *sizep = total; | 317 | { |
| 318 | void *buf = xmalloc_open_read_close(filename, sizep); | ||
| 319 | if (!buf) | ||
| 320 | bb_perror_msg_and_die("can't read '%s'", filename); | ||
| 340 | return buf; | 321 | return buf; |
| 341 | } | 322 | } |
| 342 | #endif | ||
