]> sourceware.org Git - lvm2.git/blame - daemons/common/daemon-shared.c
Common daemon code: Implement basic socket-based communication infrastructure
[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>
5
6/*
7 * Read a single message from a (socket) filedescriptor. Messages are delimited
8 * by blank lines. This call will block until all of a message is received. The
9 * memory will be allocated from heap. Upon error, all memory is freed and the
10 * buffer pointer is set to NULL.
11 */
12int read_buffer(int fd, char **buffer) {
13 int bytes = 0;
14 int buffersize = 32;
15 *buffer = malloc(buffersize + 1);
16
17 while (1) {
18 int result = read(fd, (*buffer) + bytes, buffersize - bytes);
19 if (result > 0)
20 bytes += result;
21 if (result == 0)
22 goto fail; /* we should never encounter EOF here */
23 if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK)
24 goto fail;
25
26 if (bytes == buffersize) {
27 buffersize += 1024;
28 char *new = realloc(*buffer, buffersize + 1);
29 if (new)
30 *buffer = new;
31 else
32 goto fail;
33 } else {
34 (*buffer)[bytes] = 0;
35 char *end;
36 if ((end = strstr((*buffer) + bytes - 2, "\n\n"))) {
37 *end = 0;
38 break; /* success, we have the full message now */
39 }
40 /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK */
41 }
42 }
43 return 1;
44fail:
45 free(*buffer);
46 *buffer = NULL;
47 return 0;
48}
49
50/*
51 * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
52 * SOCK_NONBLOCK) until all of the write went through.
53 *
54 * TODO use select on EWOULDBLOCK/EAGAIN to avoid useless spinning
55 */
56int write_buffer(int fd, char *buffer, int length) {
57 int written = 0;
58 while (1) {
59 int result = write(fd, buffer + written, length - written);
60 if (result > 0)
61 written += result;
62 if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
63 break; /* too bad */
64 if (written == length)
65 return 1; /* done */
66 }
67 return 0;
68}
This page took 0.025258 seconds and 5 git commands to generate.