]> git.proxmox.com Git - mirror_corosync-qdevice.git/blob - qdevices/unix-socket-client.c
qdevice-net: Log adds newline automatically
[mirror_corosync-qdevice.git] / qdevices / unix-socket-client.c
1 /*
2 * Copyright (c) 2015-2016 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 <errno.h>
36 #include <string.h>
37
38 #include "unix-socket-client.h"
39 #include "unix-socket.h"
40
41 #define UNIX_SOCKET_CLIENT_BUFFER 256
42
43 void
44 unix_socket_client_init(struct unix_socket_client *client, int sock, size_t max_receive_size,
45 size_t max_send_size, void *user_data)
46 {
47
48 memset(client, 0, sizeof(*client));
49 client->socket = sock;
50 client->user_data = user_data;
51 dynar_init(&client->receive_buffer, max_receive_size);
52 dynar_init(&client->send_buffer, max_send_size);
53 }
54
55 void
56 unix_socket_client_destroy(struct unix_socket_client *client)
57 {
58
59 dynar_destroy(&client->send_buffer);
60 dynar_destroy(&client->receive_buffer);
61 }
62
63 void
64 unix_socket_client_read_line(struct unix_socket_client *client, int enabled)
65 {
66
67 client->reading_line = enabled;
68 }
69
70 void
71 unix_socket_client_write_buffer(struct unix_socket_client *client, int enabled)
72 {
73
74 client->writing_buffer = enabled;
75 }
76
77 /*
78 * 1 Full line readed
79 * 0 Partial read (no error)
80 * -1 End of connection
81 * -2 Buffer too long
82 * -3 Unhandled error
83 */
84 int
85 unix_socket_client_io_read(struct unix_socket_client *client)
86 {
87 char buf[UNIX_SOCKET_CLIENT_BUFFER];
88 ssize_t readed;
89 int res;
90 size_t zi;
91
92 res = 0;
93 readed = unix_socket_read(client->socket, buf, sizeof(buf));
94 if (readed > 0) {
95 client->msg_already_received_bytes += readed;
96 if (dynar_cat(&client->receive_buffer, buf, readed) == -1) {
97 res = -2;
98 goto exit_err;
99 }
100
101 for (zi = 0; zi < (size_t)readed; zi++) {
102 if (buf[zi] == '\n') {
103 res = 1;
104 }
105 }
106 }
107
108 if (readed == 0) {
109 res = -1;
110 }
111
112 if (readed < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
113 res = -3;
114 }
115
116 exit_err:
117 return (res);
118 }
119
120 /*
121 * 1 All data succesfully sent
122 * 0 Partial send (no error)
123 * -1 End of connection
124 * -2 Unhandled error
125 */
126 int
127 unix_socket_client_io_write(struct unix_socket_client *client)
128 {
129 ssize_t sent;
130 size_t to_send;
131 int res;
132
133 res = 0;
134
135 to_send = dynar_size(&client->send_buffer) - client->msg_already_sent_bytes;
136 if (to_send > UNIX_SOCKET_CLIENT_BUFFER) {
137 to_send = UNIX_SOCKET_CLIENT_BUFFER;
138 }
139
140 sent = unix_socket_write(client->socket,
141 dynar_data(&client->send_buffer) + client->msg_already_sent_bytes,
142 to_send);
143
144 if (sent > 0) {
145 client->msg_already_sent_bytes += sent;
146
147 if (client->msg_already_sent_bytes == dynar_size(&client->send_buffer)) {
148 return (1);
149 }
150 }
151
152 if (sent == 0) {
153 res = -1;
154 }
155
156 if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
157 res = -2;
158 }
159
160 return (res);
161 }