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