]> sourceware.org Git - lvm2.git/blame - libdaemon/client/daemon-shared.c
remove old makefile
[lvm2.git] / libdaemon / client / 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;
98b4241b
PR
27 if (result == 0) {
28 errno = ECONNRESET;
92658f56 29 goto fail; /* we should never encounter EOF here */
98b4241b 30 }
92658f56
PR
31 if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
32 goto fail;
33
98b4241b 34 if (!strncmp((*buffer) + bytes - 4, "\n##\n", 4)) {
3556560b
PR
35 *(*buffer + bytes - 4) = 0;
36 break; /* success, we have the full message now */
37 }
38
92658f56
PR
39 if (bytes == buffersize) {
40 buffersize += 1024;
6d404585 41 if (!(new = realloc(*buffer, buffersize + 1)))
92658f56 42 goto fail;
6d404585
ZK
43
44 *buffer = new;
92658f56 45 }
3556560b 46 /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
92658f56
PR
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 61int write_buffer(int fd, const char *buffer, int length) {
a16915cb 62 static const char terminate[] = "\n##\n";
f43c89bf 63 int done = 0;
92658f56 64 int written = 0;
f43c89bf 65write:
92658f56
PR
66 while (1) {
67 int result = write(fd, buffer + written, length - written);
68 if (result > 0)
69 written += result;
70 if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
f43c89bf
PR
71 return 0; /* too bad */
72 if (written == length) {
73 if (done)
74 return 1;
75 else
76 break; /* done */
77 }
92658f56 78 }
a16915cb 79
f43c89bf
PR
80 buffer = terminate;
81 length = 4;
82 written = 0;
83 done = 1;
84 goto write;
92658f56 85}
4fcbeed6 86
14e01287 87char *format_buffer(const char *what, const char *id, va_list ap)
4fcbeed6
PR
88{
89 char *buffer, *old;
90 char *next;
aac236f4 91 int keylen;
4fcbeed6 92
14e01287 93 dm_asprintf(&buffer, "%s = \"%s\"\n", what, id);
4fcbeed6
PR
94 if (!buffer) goto fail;
95
6e4e3082 96 while ((next = va_arg(ap, char *))) {
4fcbeed6 97 old = buffer;
aac236f4
PR
98 assert(strchr(next, '='));
99 keylen = strchr(next, '=') - next;
100 if (strstr(next, "%d")) {
101 int value = va_arg(ap, int);
102 dm_asprintf(&buffer, "%s%.*s= %d\n", buffer, keylen, next, value);
103 dm_free(old);
104 } else if (strstr(next, "%s")) {
105 char *value = va_arg(ap, char *);
106 dm_asprintf(&buffer, "%s%.*s= \"%s\"\n", buffer, keylen, next, value);
107 dm_free(old);
108 } else if (strstr(next, "%b")) {
109 char *block = va_arg(ap, char *);
110 if (!block)
111 continue;
112 dm_asprintf(&buffer, "%s%.*s%s", buffer, keylen, next, block);
4fcbeed6 113 dm_free(old);
4fcbeed6
PR
114 } else {
115 dm_asprintf(&buffer, "%s%s", buffer, next);
116 dm_free(old);
4fcbeed6 117 }
aac236f4 118 if (!buffer) goto fail;
4fcbeed6
PR
119 }
120
4fcbeed6
PR
121 return buffer;
122fail:
123 dm_free(buffer);
124 return NULL;
125}
This page took 0.042299 seconds and 5 git commands to generate.