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