Move to kernel style SPDX license identifiers
[lttng-ust.git] / snprintf / patient_write.c
CommitLineData
f6da3aa6 1/*
c0c0989a 2 * SPDX-License-Identifier: LGPL-2.1-or-later
f6da3aa6 3 *
c0c0989a
MJ
4 * Copyright (C) 2009 Pierre-Marc Fournier
5 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
f6da3aa6
MD
6 */
7
b4051ad8
FD
8#include <stddef.h>
9
f6da3aa6
MD
10/* write() */
11#include <unistd.h>
12
9fe043d7
FD
13/* writev() */
14#include <sys/uio.h>
15
f6da3aa6
MD
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
28ssize_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
9fe043d7
FD
52/*
53 * The `struct iovec *iov` is not `const` because we modify it to support
54 * partial writes.
55 */
56ssize_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
f6da3aa6
MD
98ssize_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.031483 seconds and 4 git commands to generate.