embox

Форк
0
109 строк · 2.3 Кб
1

2
#include <stdbool.h>
3
#include <assert.h>
4
#include <string.h>
5
#include <stdlib.h>
6
#include <stdio.h>
7
#include <unistd.h>
8
#include <poll.h>
9

10
#include <sys/uio.h>
11
#include <util/math.h>
12

13
#include "cnc_ipc.h"
14

15
#define SSE_HEADER "data: \""
16
#define SSE_FOOTER "\"\n\n"
17

18
static int cnc_ipc_get_input_fd(void) {
19
	char *cnc_in;
20
	if (!(cnc_in = getenv(CNCIPC_IN))) {
21
		printf("Error: IPC not found");
22
		return 0;
23
	}
24

25
	return atoi(cnc_in);
26
}
27

28
static int memcpy_iov(void *dst, size_t dst_len, struct iovec *iov, int iovlen) {
29
	int i_iov;
30
	void *bp;
31
	int bp_len;
32

33
	bp = dst;
34
	bp_len = dst_len;
35
	for (i_iov = 0; i_iov < iovlen; ++i_iov) {
36
		const int to_write = min(iov[i_iov].iov_len, bp_len);
37
		memcpy(bp, iov[i_iov].iov_base, to_write);
38
		bp += to_write;
39
		bp_len -= to_write;
40
	}
41

42
	return bp - dst;
43
}
44

45
int main(int argc, char *argv[]) {
46
	const int sock = STDOUT_FILENO;
47
	const int ipc_in = cnc_ipc_get_input_fd();
48
	char buf[128], out_buf[64];
49
	struct pollfd fds[2];
50
	struct iovec iov[3];
51
	bool sock_conn, ipc_has_data;
52
	int buf_len;
53

54
	fds[0].fd = ipc_in;
55
	fds[0].events = POLLIN | POLLERR;
56
	fds[1].fd = sock;
57
	fds[1].events = POLLERR;
58

59
	buf_len = snprintf(buf, sizeof(buf),
60
		"HTTP/1.1 200 OK\r\n"
61
		"Content-Type: text/event-stream\r\n"
62
		"Cache-Control: no-cache\r\n"
63
		"Connection: keep-alive\r\n"
64
		"\r\n");
65

66
	iov[0].iov_base = SSE_HEADER;
67
	iov[0].iov_len = strlen(SSE_HEADER);
68
	iov[2].iov_base = SSE_FOOTER;
69
	iov[2].iov_len = strlen(SSE_FOOTER);
70

71
	ipc_has_data = false;
72
	sock_conn = 0 < write(sock, buf, buf_len);
73
	while (sock_conn) {
74
		if (poll(fds, 2, -1) > 0) {
75
			sock_conn = !(fds[1].revents & POLLERR);
76
			ipc_has_data = fds[0].revents & POLLIN;
77
		}
78

79
		if (sock_conn && ipc_has_data) {
80
			int buf_o;
81
			while(1) {
82
				buf_len = read(ipc_in, buf, sizeof(buf));
83
				if (buf_len > 0) {
84
					break;
85
				}
86
				usleep(1000);
87
			}
88

89
			buf_o = 0;
90
			while (buf_o < buf_len) {
91
				char *eom = memchr(buf + buf_o, '\n', buf_len - buf_o);
92
				const int body_len = eom ? eom - (buf + buf_o) : buf_len - buf_o;
93
				int write_len;
94

95
				iov[1].iov_base = buf + buf_o;
96
				iov[1].iov_len = body_len;
97

98
				write_len = memcpy_iov(out_buf, sizeof(out_buf), iov, 3);
99
				sock_conn = 0 < write(STDOUT_FILENO, out_buf, write_len);
100
				if (!sock_conn) {
101
					break;
102
				}
103

104
				buf_o += body_len + 1;
105
			}
106
		}
107
	}
108

109
	return 0;
110
}
111

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.