]> sourceware.org Git - lvm2.git/blame - daemons/common/daemon-shared.c
Fix prototypes for daemon_send_simple (const char).
[lvm2.git] / daemons / common / daemon-shared.c
CommitLineData
92658f56
PR
1#include <errno.h>
2#include <stdio.h>
3#include <malloc.h>
4#include <string.h>
6e4e3082 5#include <unistd.h>
aac236f4 6#include <assert.h>
4fcbeed6 7#include "daemon-shared.h"
92658f56
PR
8
9/*
10 * Read a single message from a (socket) filedescriptor. Messages are delimited
11 * by blank lines. This call will block until all of a message is received. The
12 * memory will be allocated from heap. Upon error, all memory is freed and the
13 * buffer pointer is set to NULL.
4fcbeed6
PR
14 *
15 * See also write_buffer about blocking (read_buffer has identical behaviour).
92658f56
PR
16 */
17int read_buffer(int fd, char **buffer) {
18 int bytes = 0;
19 int buffersize = 32;
6d404585
ZK
20 char *new;
21 char *end;
92658f56
PR
22 *buffer = malloc(buffersize + 1);
23
24 while (1) {
25 int result = read(fd, (*buffer) + bytes, buffersize - bytes);
26 if (result > 0)
27 bytes += result;
28 if (result == 0)
29 goto fail; /* we should never encounter EOF here */
30 if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
31 goto fail;
32
33 if (bytes == buffersize) {
34 buffersize += 1024;
6d404585 35 if (!(new = realloc(*buffer, buffersize + 1)))
92658f56 36 goto fail;
6d404585
ZK
37
38 *buffer = new;
92658f56
PR
39 } else {
40 (*buffer)[bytes] = 0;
f43c89bf 41 if ((end = strstr((*buffer) + bytes - 4, "\n##\n"))) {
92658f56
PR
42 *end = 0;
43 break; /* success, we have the full message now */
44 }
45 /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
46 }
47 }
48 return 1;
49fail:
50 free(*buffer);
51 *buffer = NULL;
52 return 0;
53}
54
55/*
56 * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
57 * SOCK_NONBLOCK) until all of the write went through.
58 *
59 * TODO use select on EWOULDBLOCK/EAGAIN to avoid useless spinning
60 */
f43c89bf
PR
61int write_buffer(int fd, const char *buffer, int length) {
62 int done = 0;
92658f56 63 int written = 0;
f43c89bf 64write:
92658f56
PR
65 while (1) {
66 int result = write(fd, buffer + written, length - written);
67 if (result > 0)
68 written += result;
69 if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
f43c89bf
PR
70 return 0; /* too bad */
71 if (written == length) {
72 if (done)
73 return 1;
74 else
75 break; /* done */
76 }
92658f56 77 }
f43c89bf
PR
78 const char *terminate = "\n##\n";
79 buffer = terminate;
80 length = 4;
81 written = 0;
82 done = 1;
83 goto write;
92658f56 84}
4fcbeed6 85
14e01287 86char *format_buffer(const char *what, const char *id, va_list ap)
4fcbeed6
PR
87{
88 char *buffer, *old;
89 char *next;
aac236f4 90 int keylen;
4fcbeed6 91
14e01287 92 dm_asprintf(&buffer, "%s = \"%s\"\n", what, id);
4fcbeed6
PR
93 if (!buffer) goto fail;
94
6e4e3082 95 while ((next = va_arg(ap, char *))) {
4fcbeed6 96 old = buffer;
aac236f4
PR
97 assert(strchr(next, '='));
98 keylen = strchr(next, '=') - next;
99 if (strstr(next, "%d")) {
100 int value = va_arg(ap, int);
101 dm_asprintf(&buffer, "%s%.*s= %d\n", buffer, keylen, next, value);
102 dm_free(old);
103 } else if (strstr(next, "%s")) {
104 char *value = va_arg(ap, char *);
105 dm_asprintf(&buffer, "%s%.*s= \"%s\"\n", buffer, keylen, next, value);
106 dm_free(old);
107 } else if (strstr(next, "%b")) {
108 char *block = va_arg(ap, char *);
109 if (!block)
110 continue;
111 dm_asprintf(&buffer, "%s%.*s%s", buffer, keylen, next, block);
4fcbeed6 112 dm_free(old);
4fcbeed6
PR
113 } else {
114 dm_asprintf(&buffer, "%s%s", buffer, next);
115 dm_free(old);
4fcbeed6 116 }
aac236f4 117 if (!buffer) goto fail;
4fcbeed6
PR
118 }
119
4fcbeed6
PR
120 return buffer;
121fail:
122 dm_free(buffer);
123 return NULL;
124}
This page took 0.040717 seconds and 5 git commands to generate.