/src/dovecot/src/lib/write-full.c
Line | Count | Source |
1 | | /* Copyright (c) Dovecot authors, see top-level COPYING file */ |
2 | | |
3 | | #include "lib.h" |
4 | | #include "write-full.h" |
5 | | |
6 | | #include <unistd.h> |
7 | | |
8 | | int write_full(int fd, const void *data, size_t size) |
9 | 0 | { |
10 | 0 | size_t written; |
11 | 0 | if (write_full_count(fd, data, size, &written) < 0) |
12 | 0 | return -1; |
13 | 0 | i_assert(written == size); |
14 | 0 | return 0; |
15 | 0 | } |
16 | | |
17 | | int write_full_count(int fd, const void *data, size_t size, size_t *written_r) |
18 | 0 | { |
19 | 0 | size_t pos = 0; |
20 | 0 | ssize_t ret; |
21 | |
|
22 | 0 | i_assert(size <= SSIZE_T_MAX); |
23 | | |
24 | 0 | while (pos < size) { |
25 | 0 | ret = write(fd, CONST_PTR_OFFSET(data, pos), size - pos); |
26 | 0 | if (unlikely(ret < 0)) |
27 | 0 | break; |
28 | | |
29 | 0 | if (unlikely(ret == 0)) { |
30 | | /* nothing was written, only reason for this should |
31 | | be out of disk space */ |
32 | 0 | errno = ENOSPC; |
33 | 0 | break; |
34 | 0 | } |
35 | | |
36 | 0 | pos += ret; |
37 | 0 | } |
38 | |
|
39 | 0 | *written_r = pos; |
40 | 0 | return pos == size ? 0 : -1; |
41 | 0 | } |
42 | | |
43 | | int pwrite_full(int fd, const void *data, size_t size, off_t offset) |
44 | 0 | { |
45 | 0 | ssize_t ret; |
46 | |
|
47 | 0 | i_assert(size <= SSIZE_T_MAX); |
48 | | |
49 | 0 | while (size > 0) { |
50 | 0 | ret = pwrite(fd, data, size, offset); |
51 | 0 | if (unlikely(ret < 0)) |
52 | 0 | return -1; |
53 | | |
54 | 0 | if (unlikely(ret == 0)) { |
55 | | /* nothing was written, only reason for this should |
56 | | be out of disk space */ |
57 | 0 | errno = ENOSPC; |
58 | 0 | return -1; |
59 | 0 | } |
60 | | |
61 | 0 | data = CONST_PTR_OFFSET(data, ret); |
62 | 0 | size -= ret; |
63 | 0 | offset += ret; |
64 | 0 | } |
65 | | |
66 | 0 | return 0; |
67 | 0 | } |