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