1 
2 #include <sys/types.h>
3 
4 #include <assert.h>
5 #include <errno.h>
6 #ifndef _WIN32
7 # include <poll.h>
8 #endif
9 #include <stdlib.h>
10 #include <unistd.h>
11 
12 #include "safe_rw.h"
13 
14 #ifndef _WIN32
15 ssize_t
safe_write(const int fd,const void * const buf_,size_t count,const int timeout)16 safe_write(const int fd, const void *const buf_, size_t count,
17            const int timeout)
18 {
19     struct pollfd pfd;
20     const char *buf = (const char *)buf_;
21     ssize_t written;
22 
23     pfd.fd = fd;
24     pfd.events = POLLOUT;
25 
26     while (count > (size_t) 0) {
27         while ((written = write(fd, buf, count)) <= (ssize_t) 0) {
28             if (errno == EAGAIN) {
29                 if (poll(&pfd, (nfds_t) 1, timeout) == 0) {
30                     errno = ETIMEDOUT;
31                     goto ret;
32                 }
33             } else if (errno != EINTR) {
34                 goto ret;
35             }
36         }
37         buf += written;
38         count -= (size_t) written;
39     }
40 ret:
41     return (ssize_t) (buf - (const char *)buf_);
42 }
43 
44 ssize_t
safe_read(const int fd,void * const buf_,size_t count)45 safe_read(const int fd, void *const buf_, size_t count)
46 {
47     unsigned char *buf = (unsigned char *)buf_;
48     ssize_t readnb;
49 
50     do {
51         while ((readnb = read(fd, buf, count)) < (ssize_t) 0 && errno == EINTR);
52         if (readnb < (ssize_t) 0) {
53             return readnb;
54         }
55         if (readnb == (ssize_t) 0) {
56             break;
57         }
58         count -= (size_t) readnb;
59         buf += readnb;
60     } while (count > (ssize_t) 0);
61 
62     return (ssize_t) (buf - (unsigned char *)buf_);
63 }
64 
65 ssize_t
safe_read_partial(const int fd,void * const buf_,const size_t max_count)66 safe_read_partial(const int fd, void *const buf_, const size_t max_count)
67 {
68     unsigned char *const buf = (unsigned char *)buf_;
69     ssize_t readnb;
70 
71     while ((readnb = read(fd, buf, max_count)) < (ssize_t) 0 && errno == EINTR);
72 
73     return readnb;
74 }
75 
76 #else /* _WIN32 */
77 
78 ssize_t
safe_write(const int fd,const void * const buf_,size_t count,const int timeout)79 safe_write(const int fd, const void *const buf_, size_t count,
80            const int timeout)
81 {
82     assert(fd != -1);
83     assert(buf_ != NULL);
84     assert(count > (size_t) 0U);
85     (void)timeout;
86 
87     return -1;
88 }
89 
90 ssize_t
safe_read(const int fd,void * const buf_,size_t count)91 safe_read(const int fd, void *const buf_, size_t count)
92 {
93     assert(fd != -1);
94     assert(buf_ != NULL);
95     assert(count > (size_t) 0U);
96 
97     return -1;
98 }
99 
100 ssize_t
safe_read_partial(const int fd,void * const buf_,const size_t max_count)101 safe_read_partial(const int fd, void *const buf_, const size_t max_count)
102 {
103     assert(fd != -1);
104     assert(buf_ != NULL);
105     assert(max_count > (size_t) 0U);
106 
107     return -1;
108 }
109 
110 #endif
111