]> git.proxmox.com Git - mirror_corosync-qdevice.git/blob - qdevices/qdevice-heuristics-io.c
init: Fix init scripts to work with containers
[mirror_corosync-qdevice.git] / qdevices / qdevice-heuristics-io.c
1 /*
2 * Copyright (c) 2015-2017 Red Hat, Inc.
3 *
4 * All rights reserved.
5 *
6 * Author: Jan Friesse (jfriesse@redhat.com)
7 *
8 * This software licensed under BSD license, the text of which follows:
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the Red Hat, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <limits.h>
36 #include <errno.h>
37 #include <signal.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include "qdevice-heuristics-io.h"
43
44 #define QDEVICE_HEURISTICS_IO_BUFFER_SIZE 256
45
46 ssize_t
47 qdevice_heuristics_io_blocking_write(int fd, const void *buf, size_t count)
48 {
49 ssize_t bytes_written;
50 ssize_t tmp_bytes_written;
51
52 bytes_written = 0;
53
54 do {
55 tmp_bytes_written = write(fd, (const char *)buf + bytes_written,
56 (count - bytes_written > SSIZE_MAX) ? SSIZE_MAX : count - bytes_written);
57 if (tmp_bytes_written == -1) {
58 if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) {
59 return (-1);
60 }
61 } else {
62 bytes_written += tmp_bytes_written;
63 }
64 } while ((size_t)bytes_written != count);
65
66 return (bytes_written);
67 }
68
69 /*
70 * 1 Full line readed (at least one \n found)
71 * 0 Partial read (no error)
72 * -1 End of connection
73 * -2 Buffer too long
74 * -3 Unhandled error
75 */
76 int
77 qdevice_heuristics_io_read(int fd, struct dynar *dest)
78 {
79 char buf[QDEVICE_HEURISTICS_IO_BUFFER_SIZE];
80 ssize_t readed;
81 int res;
82 size_t zi;
83
84 res = 0;
85 readed = read(fd, buf, sizeof(buf));
86 if (readed > 0) {
87 if (dynar_cat(dest, buf, readed) == -1) {
88 res = -2;
89 goto exit_err;
90 }
91
92 for (zi = 0; zi < (size_t)readed; zi++) {
93 if (buf[zi] == '\n') {
94 res = 1;
95 }
96 }
97 }
98
99 if (readed == 0) {
100 res = -1;
101 }
102
103 if (readed < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
104 res = -3;
105 }
106
107 exit_err:
108 return (res);
109 }
110
111 /*
112 * 1 All data succesfully sent
113 * 0 Partial send (no error)
114 * -1 send returned 0,
115 * -2 Unhandled error
116 */
117 int
118 qdevice_heuristics_io_write(int fd, const struct dynar *msg, size_t *already_sent_bytes)
119 {
120 ssize_t sent;
121 size_t to_send;
122 int res;
123
124 res = 0;
125
126 to_send = dynar_size(msg) - *already_sent_bytes;
127 if (to_send > QDEVICE_HEURISTICS_IO_BUFFER_SIZE) {
128 to_send = QDEVICE_HEURISTICS_IO_BUFFER_SIZE;
129 }
130
131 sent = write(fd, dynar_data(msg) + *already_sent_bytes,
132 to_send);
133
134 if (sent > 0) {
135 *already_sent_bytes += sent;
136
137 if (*already_sent_bytes == dynar_size(msg)) {
138 return (1);
139 }
140 }
141
142 if (sent == 0) {
143 res = -1;
144 }
145
146 if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
147 res = -2;
148 }
149
150 return (res);
151 }