#include #include #include #include #include #include #include #include #include "io.h" int read_all(int fd, unsigned char *buf, size_t len) { ssize_t nbytes; while (len > 0) { nbytes = read(fd, buf, len); if (nbytes == 0) { errno = EPIPE; return -1; } if (nbytes < 0 && errno == EINTR) continue; if (nbytes < 0) return -1; buf += nbytes; len -= nbytes; } return 0; } int read_some(int fd, unsigned char *buf, size_t *lenp) { ssize_t nbytes; do nbytes = read(fd, buf, *lenp); while (nbytes < 0 && errno == EINTR); if (nbytes == 0) { errno = EPIPE; return -1; } if (nbytes < 0) return -1; *lenp = nbytes; return 0; } int read_char(int fd) { ssize_t nbytes; char buf[1]; do nbytes = read(fd, buf, 1); while (nbytes < 0 && errno == EINTR); if (nbytes < 0) return -1; if (nbytes == 0) { errno = EPIPE; return -1; } return buf[0]; } int write_all(int fd, const unsigned char *buf, size_t count) { ssize_t nbytes; while (count > 0) { nbytes = write(fd, buf, count); if (nbytes < 0 && errno == EINTR) continue; if (nbytes < 0) return -1; buf += nbytes; count -= nbytes; } return 0; } int write_char(int fd, char c) { ssize_t nbytes; char buf[1] = {c}; do nbytes = write(fd, buf, 1); while (nbytes < 0 && errno == EINTR); if (nbytes < 0) return -1; if (nbytes == 0) { errno = EPIPE; return -1; } return 0; } ssize_t read_file(char *buf, size_t len, const char *fmt, ...) { va_list ap; int rc; struct stat st; int fd; va_start(ap, fmt); rc = vsnprintf(buf, len, fmt, ap); va_end(ap); if (rc < 0) return -1; if ((size_t)rc >= len) { errno = ENAMETOOLONG; return -1; } rc = stat(buf, &st); if (rc < 0) return -1; if ((size_t)st.st_size > len-1) { errno = EMSGSIZE; return -1; } fd = open(buf, O_RDONLY); if (fd < 0) return -1; rc = read_all(fd, (unsigned char *)buf, st.st_size); if (rc < 0) return -1; buf[(size_t)st.st_size] = '\0'; close(fd); return st.st_size; } char *read_full(int fd) { int rc; struct stat st; rc = fstat(fd, &st); if (rc < 0) return NULL; char *buf = malloc(st.st_size + 1); if (buf == NULL) return NULL; rc = read_all(fd, (unsigned char *)buf, st.st_size); if (rc < 0) return NULL; buf[(size_t)st.st_size] = '\0'; close(fd); return buf; }