1 
2 #include <config.h>
3 
4 #include "ftpd.h"
5 #include "safe_rw.h"
6 
7 #ifdef WITH_DMALLOC
8 # include <dmalloc.h>
9 #endif
10 
11 ssize_t
safe_write(const int fd,const void * const buf_,size_t count,const int timeout)12 safe_write(const int fd, const void * const buf_, size_t count,
13            const int timeout)
14 {
15     struct pollfd  pfd;
16     const char    *buf = (const char *) buf_;
17     ssize_t        written;
18 
19     pfd.fd = fd;
20     pfd.events = POLLOUT;
21 
22     while (count > (size_t) 0) {
23         while ((written = write(fd, buf, count)) <= (ssize_t) 0) {
24             if (errno == EAGAIN) {
25                 if (poll(&pfd, (nfds_t) 1, timeout) == 0) {
26                     errno = ETIMEDOUT;
27                     goto ret;
28                 }
29             } else if (errno != EINTR) {
30                 goto ret;
31             }
32         }
33         buf += written;
34         count -= written;
35     }
36 ret:
37     return (ssize_t) (buf - (const char *) buf_);
38 }
39 
40 ssize_t
safe_read(const int fd,void * const buf_,size_t count)41 safe_read(const int fd, void * const buf_, size_t count)
42 {
43     unsigned char *buf = (unsigned char *) buf_;
44     ssize_t        readnb;
45 
46     while (count > (ssize_t) 0) {
47         while ((readnb = read(fd, buf, count)) < (ssize_t) 0 &&
48                errno == EINTR);
49         if (readnb < (ssize_t) 0) {
50             return readnb;
51         }
52         if (readnb == (ssize_t) 0) {
53             break;
54         }
55         count -= readnb;
56         buf += readnb;
57     }
58 
59     return (ssize_t) (buf - (unsigned char *) buf_);
60 }
61 
62 ssize_t
safe_read_partial(const int fd,void * const buf_,const size_t max_count)63 safe_read_partial(const int fd, void * const buf_, const size_t max_count)
64 {
65     unsigned char * const buf = (unsigned char *) buf_;
66     ssize_t               readnb;
67 
68     while ((readnb = read(fd, buf, max_count)) < (ssize_t) 0 &&
69            errno == EINTR);
70 
71     return readnb;
72 }
73