Move to kernel style SPDX license identifiers
[lttng-ust.git] / snprintf / patient_write.c
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-or-later
3 *
4 * Copyright (C) 2009 Pierre-Marc Fournier
5 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 */
7
8 #include <stddef.h>
9
10 /* write() */
11 #include <unistd.h>
12
13 /* writev() */
14 #include <sys/uio.h>
15
16 /* send() */
17 #include <sys/types.h>
18 #include <sys/socket.h>
19
20 #include <errno.h>
21
22 #include <share.h>
23
24 /*
25 * This write is patient because it restarts if it was incomplete.
26 */
27
28 ssize_t patient_write(int fd, const void *buf, size_t count)
29 {
30 const char *bufc = (const char *) buf;
31 int result;
32
33 for(;;) {
34 result = write(fd, bufc, count);
35 if (result == -1 && errno == EINTR) {
36 continue;
37 }
38 if (result <= 0) {
39 return result;
40 }
41 count -= result;
42 bufc += result;
43
44 if (count == 0) {
45 break;
46 }
47 }
48
49 return bufc-(const char *)buf;
50 }
51
52 /*
53 * The `struct iovec *iov` is not `const` because we modify it to support
54 * partial writes.
55 */
56 ssize_t patient_writev(int fd, struct iovec *iov, int iovcnt)
57 {
58 ssize_t written, total_written = 0;
59 int curr_element_idx = 0;
60
61 for(;;) {
62 written = writev(fd, iov + curr_element_idx,
63 iovcnt - curr_element_idx);
64 if (written == -1 && errno == EINTR) {
65 continue;
66 }
67 if (written <= 0) {
68 return written;
69 }
70
71 total_written += written;
72
73 /*
74 * If it's not the last element in the vector and we have
75 * written more than the current element size, then increment
76 * the current element index until we reach the element that
77 * was partially written.
78 */
79 while (curr_element_idx < iovcnt &&
80 written >= iov[curr_element_idx].iov_len) {
81 written -= iov[curr_element_idx].iov_len;
82 curr_element_idx++;
83 }
84
85 /* Maybe we are done. */
86 if (curr_element_idx >= iovcnt) {
87 break;
88 }
89
90 /* Update the current element base and size. */
91 iov[curr_element_idx].iov_base += written;
92 iov[curr_element_idx].iov_len -= written;
93 }
94
95 return total_written;
96 }
97
98 ssize_t patient_send(int fd, const void *buf, size_t count, int flags)
99 {
100 const char *bufc = (const char *) buf;
101 int result;
102
103 for(;;) {
104 result = send(fd, bufc, count, flags);
105 if (result == -1 && errno == EINTR) {
106 continue;
107 }
108 if (result <= 0) {
109 return result;
110 }
111 count -= result;
112 bufc += result;
113
114 if (count == 0) {
115 break;
116 }
117 }
118
119 return bufc - (const char *) buf;
120 }
This page took 0.031461 seconds and 4 git commands to generate.