]> sourceware.org Git - lvm2.git/blame - libdaemon/client/daemon-shared.c
Reflect new file locations, include file updates etc.
[lvm2.git] / libdaemon / client / daemon-shared.c
CommitLineData
7126d8c2
AK
1/*
2 * Copyright (C) 2011-2012 Red Hat, Inc.
3 *
4 * This file is part of LVM2.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU Lesser General Public License v.2.1.
9 *
10 * You should have received a copy of the GNU Lesser General Public License
11 * along with this program; if not, write to the Free Software Foundation,
12 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13 */
14
92658f56
PR
15#include <errno.h>
16#include <stdio.h>
17#include <malloc.h>
18#include <string.h>
6e4e3082 19#include <unistd.h>
aac236f4 20#include <assert.h>
7126d8c2 21
4fcbeed6 22#include "daemon-shared.h"
7126d8c2 23#include "libdevmapper.h"
92658f56
PR
24
25/*
26 * Read a single message from a (socket) filedescriptor. Messages are delimited
27 * by blank lines. This call will block until all of a message is received. The
28 * memory will be allocated from heap. Upon error, all memory is freed and the
29 * buffer pointer is set to NULL.
4fcbeed6
PR
30 *
31 * See also write_buffer about blocking (read_buffer has identical behaviour).
92658f56
PR
32 */
33int read_buffer(int fd, char **buffer) {
34 int bytes = 0;
35 int buffersize = 32;
6d404585 36 char *new;
92658f56
PR
37 *buffer = malloc(buffersize + 1);
38
39 while (1) {
40 int result = read(fd, (*buffer) + bytes, buffersize - bytes);
41 if (result > 0)
42 bytes += result;
98b4241b
PR
43 if (result == 0) {
44 errno = ECONNRESET;
92658f56 45 goto fail; /* we should never encounter EOF here */
98b4241b 46 }
92658f56
PR
47 if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
48 goto fail;
49
98b4241b 50 if (!strncmp((*buffer) + bytes - 4, "\n##\n", 4)) {
3556560b
PR
51 *(*buffer + bytes - 4) = 0;
52 break; /* success, we have the full message now */
53 }
54
92658f56
PR
55 if (bytes == buffersize) {
56 buffersize += 1024;
6d404585 57 if (!(new = realloc(*buffer, buffersize + 1)))
92658f56 58 goto fail;
6d404585
ZK
59
60 *buffer = new;
92658f56 61 }
3556560b 62 /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
92658f56
PR
63 }
64 return 1;
65fail:
66 free(*buffer);
67 *buffer = NULL;
68 return 0;
69}
70
71/*
72 * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
73 * SOCK_NONBLOCK) until all of the write went through.
74 *
75 * TODO use select on EWOULDBLOCK/EAGAIN to avoid useless spinning
76 */
f43c89bf 77int write_buffer(int fd, const char *buffer, int length) {
a16915cb 78 static const char terminate[] = "\n##\n";
f43c89bf 79 int done = 0;
92658f56 80 int written = 0;
f43c89bf 81write:
92658f56
PR
82 while (1) {
83 int result = write(fd, buffer + written, length - written);
84 if (result > 0)
85 written += result;
86 if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
f43c89bf
PR
87 return 0; /* too bad */
88 if (written == length) {
89 if (done)
90 return 1;
91 else
92 break; /* done */
93 }
92658f56 94 }
a16915cb 95
f43c89bf
PR
96 buffer = terminate;
97 length = 4;
98 written = 0;
99 done = 1;
100 goto write;
92658f56 101}
4fcbeed6 102
14e01287 103char *format_buffer(const char *what, const char *id, va_list ap)
4fcbeed6
PR
104{
105 char *buffer, *old;
106 char *next;
aac236f4 107 int keylen;
4fcbeed6 108
14e01287 109 dm_asprintf(&buffer, "%s = \"%s\"\n", what, id);
4fcbeed6
PR
110 if (!buffer) goto fail;
111
6e4e3082 112 while ((next = va_arg(ap, char *))) {
4fcbeed6 113 old = buffer;
aac236f4
PR
114 assert(strchr(next, '='));
115 keylen = strchr(next, '=') - next;
116 if (strstr(next, "%d")) {
117 int value = va_arg(ap, int);
118 dm_asprintf(&buffer, "%s%.*s= %d\n", buffer, keylen, next, value);
119 dm_free(old);
120 } else if (strstr(next, "%s")) {
121 char *value = va_arg(ap, char *);
122 dm_asprintf(&buffer, "%s%.*s= \"%s\"\n", buffer, keylen, next, value);
123 dm_free(old);
124 } else if (strstr(next, "%b")) {
125 char *block = va_arg(ap, char *);
126 if (!block)
127 continue;
128 dm_asprintf(&buffer, "%s%.*s%s", buffer, keylen, next, block);
4fcbeed6 129 dm_free(old);
4fcbeed6
PR
130 } else {
131 dm_asprintf(&buffer, "%s%s", buffer, next);
132 dm_free(old);
4fcbeed6 133 }
aac236f4 134 if (!buffer) goto fail;
4fcbeed6
PR
135 }
136
4fcbeed6
PR
137 return buffer;
138fail:
139 dm_free(buffer);
140 return NULL;
141}
This page took 0.054128 seconds and 5 git commands to generate.