| /* vi: set sw=4 ts=4: */ | |
| /* | |
| * Utility routines. | |
| * | |
| * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | |
| * | |
| * Licensed under GPLv2 or later, see file LICENSE in this source tree. | |
| */ | |
| #include "libbb.h" | |
| ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) | |
| { | |
| ssize_t n; | |
| for (;;) { | |
| n = read(fd, buf, count); | |
| 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; | |
| } | |
| /* | |
| * Read all of the supplied buffer from a file. | |
| * This does multiple reads as necessary. | |
| * Returns the amount read, or -1 on an error. | |
| * A short read is returned on an end of file. | |
| */ | |
| ssize_t FAST_FUNC full_read(int fd, void *buf, size_t len) | |
| { | |
| ssize_t cc; | |
| ssize_t total; | |
| total = 0; | |
| while (len) { | |
| cc = safe_read(fd, buf, len); | |
| 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; | |
| } | |
| return total; | |
| } | |
| ssize_t FAST_FUNC read_close(int fd, void *buf, size_t size) | |
| { | |
| /*int e;*/ | |
| size = full_read(fd, buf, size); | |
| /*e = errno;*/ | |
| close(fd); | |
| /*errno = e;*/ | |
| return 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); | |
| } |