/* Copyright (C) 2019 C. McEnroe * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include int main(void) { int error; // TODO: Read info from file. const char *path = "example.sock"; int server = socket(PF_LOCAL, SOCK_STREAM, 0); if (server < 0) err(EX_OSERR, "socket"); struct sockaddr_un addr = { .sun_family = AF_LOCAL }; strncpy(addr.sun_path, path, sizeof(addr.sun_path)); error = bind(server, (struct sockaddr *)&addr, SUN_LEN(&addr)); if (error) err(EX_CANTCREAT, "%s", path); error = listen(server, 0); if (error) err(EX_OSERR, "listen"); int maxClient = server; struct pollfd fds[2] = { { .events = POLLIN, .fd = STDIN_FILENO }, { .events = POLLIN, .fd = server }, }; 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"); int client = server + 1; while (client <= maxClient) { ssize_t wlen = write(client, buf, rlen); if (wlen == rlen) { client++; continue; } close(client); if (client < maxClient) { int fd = dup(maxClient); assert(fd == client); close(maxClient); } maxClient--; } // TODO: Update local terminal. } if (fds[1].revents) { int client = accept(server, NULL, NULL); if (client < 0) err(EX_IOERR, "accept"); maxClient++; assert(client == maxClient); int yes = 1; fcntl(client, F_SETFL, O_NONBLOCK); error = setsockopt(client, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(yes)); if (error) err(EX_IOERR, "setsockopt"); // TODO: Send snapshot. } } err(EX_IOERR, "poll"); }