1/* copy-paste from BusyBox */ 2 3#include <autoconf.h> 4#include <libbb.h> 5 6#include <stdio.h> 7#include <string.h> 8#include <malloc.h> 9 10const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted"; 11int *const bb_errno; 12int xfunc_error_retval = EXIT_FAILURE; 13 14void FAST_FUNC xfunc_die(void) 15{ 16 exit(xfunc_error_retval); 17} 18 19void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) 20{ 21 /* do nothing */ 22} 23 24void FAST_FUNC bb_error_msg_and_die(const char *s, ...) 25{ 26 va_list p; 27 28 va_start(p, s); 29 bb_verror_msg(s, p, NULL); 30 va_end(p); 31 xfunc_die(); 32} 33 34void FAST_FUNC bb_error_msg(const char *s, ...) 35{ 36 va_list p; 37 38 va_start(p, s); 39 bb_verror_msg(s, p, NULL); 40 va_end(p); 41} 42 43/* All the functions starting with "x" call bb_error_msg_and_die() if they 44 * fail, so callers never need to check for errors. If it returned, it 45 * succeeded. */ 46 47#ifndef DMALLOC 48/* dmalloc provides variants of these that do abort() on failure. 49 * Since dmalloc's prototypes overwrite the impls here as they are 50 * included after these prototypes in libbb.h, all is well. 51 */ 52// Die if we can't allocate size bytes of memory. 53void* FAST_FUNC xmalloc(size_t size) 54{ 55 void *ptr = malloc(size); 56 if (ptr == NULL && size != 0) 57 bb_error_msg_and_die(bb_msg_memory_exhausted); 58 return ptr; 59} 60 61// Die if we can't resize previously allocated memory. (This returns a pointer 62// to the new memory, which may or may not be the same as the old memory. 63// It'll copy the contents to a new chunk and free the old one if necessary.) 64void* FAST_FUNC xrealloc(void *ptr, size_t size) 65{ 66 ptr = realloc(ptr, size); 67 if (ptr == NULL && size != 0) 68 bb_error_msg_and_die(bb_msg_memory_exhausted); 69 return ptr; 70} 71#endif /* DMALLOC */ 72 73ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) 74{ 75 ssize_t n; 76 77 do { 78 n = read(fd, buf, count); 79 } while (n < 0 && errno == EINTR); 80 81 return n; 82} 83 84/* 85 * Read all of the supplied buffer from a file. 86 * This does multiple reads as necessary. 87 * Returns the amount read, or -1 on an error. 88 * A short read is returned on an end of file. 89 */ 90ssize_t FAST_FUNC full_read(int fd, void *buf, size_t len) 91{ 92 ssize_t cc; 93 ssize_t total; 94 95 total = 0; 96 97 while (len) { 98 cc = safe_read(fd, buf, len); 99 100 if (cc < 0) { 101 if (total) { 102 /* we already have some! */ 103 /* user can do another read to know the error code */ 104 return total; 105 } 106 return cc; /* read() returns -1 on failure. */ 107 } 108 if (cc == 0) 109 break; 110 buf = ((char *)buf) + cc; 111 total += cc; 112 len -= cc; 113 } 114 115 return total; 116} 117