summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-07-28 22:38:14 -0400
committerJune McEnroe <june@causal.agency>2019-07-28 22:38:14 -0400
commit179a8669e3c000ecff4983534c79a397d1d59dc5 (patch)
tree234eba4b394d6846432b3efdc90b372b8a33461b
parentAdd empty commands (diff)
downloadstream-179a8669e3c000ecff4983534c79a397d1d59dc5.tar.gz
stream-179a8669e3c000ecff4983534c79a397d1d59dc5.zip
Do basic multiplexing in ingest
-rw-r--r--ingest.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/ingest.c b/ingest.c
index dde890a..d0b8bca 100644
--- a/ingest.c
+++ b/ingest.c
@@ -14,11 +14,79 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <assert.h>
 #include <err.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 #include <sysexits.h>
+#include <unistd.h>
 
 int main(void) {
-	// TODO: Read info, listen on socket, emulate terminal.
+	int error;
+
+	// TODO: Read info from file.
+	const char *path = "example.sock";
+	
+	int sock = socket(PF_LOCAL, SOCK_STREAM, 0);
+	if (sock < 0) err(EX_OSERR, "socket");
+
+	struct sockaddr_un addr = { .sun_family = AF_LOCAL };
+	strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+	error = bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr));
+	if (error) err(EX_CANTCREAT, "%s", path);
+
+	error = listen(sock, 0);
+	if (error) err(EX_OSERR, "listen");
+
+	uint32_t clients[8] = {0};
+
+	struct pollfd fds[2] = {
+		{ .events = POLLIN, .fd = STDIN_FILENO },
+		{ .events = POLLIN, .fd = sock },
+	};
+	while (0 < poll(fds, 2, -1)) {
+		if (fds[0].revents) {
+			char buf[4096];
+			ssize_t rlen = read(STDIN_FILENO, buf, sizeof(buf));
+			if (rlen < 0) err(EX_IOERR, "read");
+
+			// TODO: Update local terminal.
+
+			for (int i = 0; i < 8; ++i) {
+				if (!clients[i]) continue;
+				for (int j = 0; j < 32; ++j) {
+					if (!(clients[i] & 1UL << j)) continue;
+					int fd = 32 * i + j;
+
+					ssize_t wlen = write(fd, buf, rlen);
+					if (wlen < 0) {
+						close(fd);
+						clients[i] &= ~(1UL << j);
+					}
+				}
+			}
+		}
+
+		if (fds[1].revents) {
+			int fd = accept(sock, NULL, NULL);
+			if (fd < 0) err(EX_IOERR, "accept");
+			fcntl(fd, F_SETFL, O_NONBLOCK);
+
+			int yes = 1;
+			error = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(yes));
+			if (error) err(EX_IOERR, "setsockopt");
+
+			assert(fd < 256);
+			clients[fd / 64] |= 1 << (fd % 64);
+
+			// TODO: Send snapshot.
+		}
+	}
+	err(EX_IOERR, "poll");
 }