X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fread.c;h=a342506a8e738699f0f231c854e8b2f2be365162;hb=HEAD;hp=861828da19e316f297046a9835562ccfa480b220;hpb=3a34d0c08a77ee48edc3f4353cc49b95aba85c2f;p=oweals%2Fbusybox.git diff --git a/libbb/read.c b/libbb/read.c index 861828da1..a342506a8 100644 --- a/libbb/read.c +++ b/libbb/read.c @@ -4,18 +4,25 @@ * * Copyright (C) 1999-2004 by Erik Andersen * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - #include "libbb.h" -ssize_t safe_read(int fd, void *buf, size_t count) +ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) { ssize_t n; - do { + for (;;) { n = read(fd, buf, count); - } while (n < 0 && errno == EINTR); + if (n >= 0 || errno != EINTR) + break; + /* Some callers set errno=0, are upset when they see EINTR. + * Returning EINTR is wrong since we retry read(), + * the "error" was transient. + */ + errno = 0; + /* repeat the read() */ + } return n; } @@ -26,7 +33,7 @@ ssize_t safe_read(int fd, void *buf, size_t count) * Returns the amount read, or -1 on an error. * A short read is returned on an end of file. */ -ssize_t full_read(int fd, void *buf, size_t len) +ssize_t FAST_FUNC full_read(int fd, void *buf, size_t len) { ssize_t cc; ssize_t total; @@ -36,12 +43,16 @@ ssize_t full_read(int fd, void *buf, size_t len) while (len) { cc = safe_read(fd, buf, len); - if (cc < 0) - return cc; /* read() returns -1 on failure. */ - + if (cc < 0) { + if (total) { + /* we already have some! */ + /* user can do another read to know the error code */ + return total; + } + return cc; /* read() returns -1 on failure. */ + } if (cc == 0) break; - buf = ((char *)buf) + cc; total += cc; len -= cc; @@ -50,88 +61,20 @@ ssize_t full_read(int fd, void *buf, size_t len) return total; } -// Die with an error message if we can't read the entire buffer. -void xread(int fd, void *buf, size_t count) -{ - if (count) { - ssize_t size = full_read(fd, buf, count); - if (size != count) - bb_error_msg_and_die("short read"); - } -} - -// Die with an error message if we can't read one character. -unsigned char xread_char(int fd) -{ - char tmp; - - xread(fd, &tmp, 1); - - return tmp; -} - -// Read one line a-la fgets. Works only on seekable streams -char *reads(int fd, char *buffer, size_t size) -{ - char *p; - - if (size < 2) - return NULL; - size = full_read(fd, buffer, size-1); - if ((ssize_t)size <= 0) - return NULL; - - buffer[size] = '\0'; - p = strchr(buffer, '\n'); - if (p) { - off_t offset; - *p++ = '\0'; - // avoid incorrect (unsigned) widening - offset = (off_t)(p-buffer) - (off_t)size; - // set fd position right after '\n' - if (offset && lseek(fd, offset, SEEK_CUR) == (off_t)-1) - return NULL; - } - return buffer; -} - -ssize_t read_close(int fd, void *buf, size_t size) +ssize_t FAST_FUNC read_close(int fd, void *buf, size_t size) { - int e; + /*int e;*/ size = full_read(fd, buf, size); - e = errno; + /*e = errno;*/ close(fd); - errno = e; + /*errno = e;*/ return size; } -ssize_t open_read_close(const char *filename, void *buf, size_t size) +ssize_t FAST_FUNC open_read_close(const char *filename, void *buf, size_t size) { int fd = open(filename, O_RDONLY); if (fd < 0) return fd; return read_close(fd, buf, size); } - -void *xmalloc_open_read_close(const char *filename, size_t *sizep) -{ - char *buf; - size_t size = sizep ? *sizep : INT_MAX; - int fd = xopen(filename, O_RDONLY); - /* /proc/N/stat files report len 0 here */ - /* In order to make such files readable, we add small const */ - off_t len = xlseek(fd, 0, SEEK_END) + 256; - xlseek(fd, 0, SEEK_SET); - - if (len > size) - bb_error_msg_and_die("file '%s' is too big", filename); - size = len; - buf = xmalloc(size + 1); - size = read_close(fd, buf, size); - if ((ssize_t)size < 0) - bb_perror_msg_and_die("'%s'", filename); - xrealloc(buf, size + 1); - buf[size] = '\0'; - if (sizep) *sizep = size; - return buf; -}