]> sourceware.org Git - lvm2.git/blame - daemons/common/daemon-shared.c
Add tentative documentation of pvscan --lvmetad to the pvscan manpage.
[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 20 char *new;
92658f56
PR
21 *buffer = malloc(buffersize + 1);
22
23 while (1) {
24 int result = read(fd, (*buffer) + bytes, buffersize - bytes);
25 if (result > 0)
26 bytes += result;
27 if (result == 0)
28 goto fail; /* we should never encounter EOF here */
29 if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
30 goto fail;
31
3556560b
PR
32 if ((!strncmp((*buffer) + bytes - 4, "\n##\n", 4))) {
33 *(*buffer + bytes - 4) = 0;
34 break; /* success, we have the full message now */
35 }
36
92658f56
PR
37 if (bytes == buffersize) {
38 buffersize += 1024;
6d404585 39 if (!(new = realloc(*buffer, buffersize + 1)))
92658f56 40 goto fail;
6d404585
ZK
41
42 *buffer = new;
92658f56 43 }
3556560b 44 /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
92658f56
PR
45 }
46 return 1;
47fail:
48 free(*buffer);
49 *buffer = NULL;
50 return 0;
51}
52
53/*
54 * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
55 * SOCK_NONBLOCK) until all of the write went through.
56 *
57 * TODO use select on EWOULDBLOCK/EAGAIN to avoid useless spinning
58 */
f43c89bf 59int write_buffer(int fd, const char *buffer, int length) {
a16915cb 60 static const char terminate[] = "\n##\n";
f43c89bf 61 int done = 0;
92658f56 62 int written = 0;
f43c89bf 63write:
92658f56
PR
64 while (1) {
65 int result = write(fd, buffer + written, length - written);
66 if (result > 0)
67 written += result;
68 if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
f43c89bf
PR
69 return 0; /* too bad */
70 if (written == length) {
71 if (done)
72 return 1;
73 else
74 break; /* done */
75 }
92658f56 76 }
a16915cb 77
f43c89bf
PR
78 buffer = terminate;
79 length = 4;
80 written = 0;
81 done = 1;
82 goto write;
92658f56 83}
4fcbeed6 84
14e01287 85char *format_buffer(const char *what, const char *id, va_list ap)
4fcbeed6
PR
86{
87 char *buffer, *old;
88 char *next;
aac236f4 89 int keylen;
4fcbeed6 90
14e01287 91 dm_asprintf(&buffer, "%s = \"%s\"\n", what, id);
4fcbeed6
PR
92 if (!buffer) goto fail;
93
6e4e3082 94 while ((next = va_arg(ap, char *))) {
4fcbeed6 95 old = buffer;
aac236f4
PR
96 assert(strchr(next, '='));
97 keylen = strchr(next, '=') - next;
98 if (strstr(next, "%d")) {
99 int value = va_arg(ap, int);
100 dm_asprintf(&buffer, "%s%.*s= %d\n", buffer, keylen, next, value);
101 dm_free(old);
102 } else if (strstr(next, "%s")) {
103 char *value = va_arg(ap, char *);
104 dm_asprintf(&buffer, "%s%.*s= \"%s\"\n", buffer, keylen, next, value);
105 dm_free(old);
106 } else if (strstr(next, "%b")) {
107 char *block = va_arg(ap, char *);
108 if (!block)
109 continue;
110 dm_asprintf(&buffer, "%s%.*s%s", buffer, keylen, next, block);
4fcbeed6 111 dm_free(old);
4fcbeed6
PR
112 } else {
113 dm_asprintf(&buffer, "%s%s", buffer, next);
114 dm_free(old);
4fcbeed6 115 }
aac236f4 116 if (!buffer) goto fail;
4fcbeed6
PR
117 }
118
4fcbeed6
PR
119 return buffer;
120fail:
121 dm_free(buffer);
122 return NULL;
123}
This page took 0.044578 seconds and 5 git commands to generate.