/* Minimalist POSIX I/O (unbuffered, dies on error) * J. Welsh, May 2019 */ #include #include #include #include #include "io.h" void write_all(int fd, char const *buf, size_t len) { while (len) { ssize_t n = write(fd,buf,len); if (n < 0) { if (errno == EINTR) continue; if (fd != 2) /* prevent loop */ perr("write_all"); _exit(errno); } buf += n; len -= n; } } size_t read_all(int fd, unsigned char *buf, size_t len) { size_t olen = len; while (len) { ssize_t n = read(fd,buf,len); if (n <= 0) { if (n) { if (errno == EINTR) continue; perr("read_all"); _exit(errno); } break; } buf += n; len -= n; } return olen - len; } void write_str(int fd, char const *s) { write_all(fd,s,strlen(s)); } void newline(int fd) { write_all(fd,"\n",1); } void write_line(int fd, char const *s) { write_str(fd,s); newline(fd); } void assert_fail(char const *expr) { write_str(2,"Assertion failed: "); write_line(2,expr); raise(SIGABRT); _exit(1); } void perr(char const *context) { write_str(2,context); write_str(2,": "); write_line(2,strerror(errno)); } int chkp(char const *context, int ret) { if (ret == -1) { perr(context); _exit(errno); } return ret; }