Projects : keksum : keksum_genesis
1 | /* Minimalist POSIX I/O (unbuffered, dies on error) |
2 | * J. Welsh, May 2019 |
3 | */ |
4 | |
5 | #include <errno.h> |
6 | #include <signal.h> |
7 | #include <string.h> |
8 | #include <unistd.h> |
9 | #include "io.h" |
10 | |
11 | void write_all(int fd, char const *buf, size_t len) { |
12 | while (len) { |
13 | ssize_t n = write(fd,buf,len); |
14 | if (n < 0) { |
15 | if (errno == EINTR) continue; |
16 | if (fd != 2) /* prevent loop */ |
17 | perr("write_all"); |
18 | _exit(errno); |
19 | } |
20 | buf += n; |
21 | len -= n; |
22 | } |
23 | } |
24 | |
25 | size_t read_all(int fd, unsigned char *buf, size_t len) { |
26 | size_t olen = len; |
27 | while (len) { |
28 | ssize_t n = read(fd,buf,len); |
29 | if (n <= 0) { |
30 | if (n) { |
31 | if (errno == EINTR) continue; |
32 | perr("read_all"); |
33 | _exit(errno); |
34 | } |
35 | break; |
36 | } |
37 | buf += n; |
38 | len -= n; |
39 | } |
40 | return olen - len; |
41 | } |
42 | |
43 | void write_str(int fd, char const *s) { |
44 | write_all(fd,s,strlen(s)); |
45 | } |
46 | |
47 | void newline(int fd) { |
48 | write_all(fd,"\n",1); |
49 | } |
50 | |
51 | void write_line(int fd, char const *s) { |
52 | write_str(fd,s); |
53 | newline(fd); |
54 | } |
55 | |
56 | void assert_fail(char const *expr) { |
57 | write_str(2,"Assertion failed: "); |
58 | write_line(2,expr); |
59 | raise(SIGABRT); |
60 | _exit(1); |
61 | } |
62 | |
63 | void perr(char const *context) { |
64 | write_str(2,context); |
65 | write_str(2,": "); |
66 | write_line(2,strerror(errno)); |
67 | } |
68 | |
69 | int chkp(char const *context, int ret) { |
70 | if (ret == -1) { |
71 | perr(context); |
72 | _exit(errno); |
73 | } |
74 | return ret; |
75 | } |