diff options
Diffstat (limited to 'bin/pbd.c')
-rw-r--r-- | bin/pbd.c | 78 |
1 files changed, 37 insertions, 41 deletions
diff --git a/bin/pbd.c b/bin/pbd.c index 28e61754..80ab036f 100644 --- a/bin/pbd.c +++ b/bin/pbd.c @@ -16,9 +16,9 @@ #include <arpa/inet.h> #include <err.h> +#include <fcntl.h> #include <netinet/in.h> #include <stdbool.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> @@ -26,24 +26,24 @@ #include <sysexits.h> #include <unistd.h> -static void spawn(const char *cmd, int childFd, int parentFd) { +#define UNUSED __attribute__((unused)) + +static void spawn(const char *cmd, int dest, int src) { pid_t pid = fork(); if (pid < 0) err(EX_OSERR, "fork"); if (pid) { int status; - pid_t wait = waitpid(pid, &status, 0); - if (wait < 0) err(EX_OSERR, "waitpid"); + pid_t dead = waitpid(pid, &status, 0); + if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid); + if (status) warnx("%s: status %d", cmd, status); - if (status) { - warnx("child %s status %d", cmd, status); - } } else { - int fd = dup2(parentFd, childFd); + int fd = dup2(src, dest); if (fd < 0) err(EX_OSERR, "dup2"); - int error = execlp(cmd, cmd, NULL); - if (error) err(EX_OSERR, "execlp"); + execlp(cmd, cmd, NULL); + err(EX_UNAVAILABLE, "%s", cmd); } } @@ -53,34 +53,36 @@ static int pbd(void) { int server = socket(PF_INET, SOCK_STREAM, 0); if (server < 0) err(EX_OSERR, "socket"); + error = fcntl(server, F_SETFD, FD_CLOEXEC); + if (error) err(EX_IOERR, "fcntl"); + struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(7062), .sin_addr = { .s_addr = htonl(0x7f000001) }, }; - error = bind(server, (struct sockaddr *)&addr, sizeof(addr)); - if (error) err(EX_OSERR, "bind"); + if (error) err(EX_UNAVAILABLE, "bind"); - error = listen(server, 1); - if (error) err(EX_OSERR, "listen"); + error = listen(server, 0); + if (error) err(EX_UNAVAILABLE, "listen"); for (;;) { int client = accept(server, NULL, NULL); - if (client < 0) err(EX_OSERR, "accept"); + if (client < 0) err(EX_IOERR, "accept"); + + error = fcntl(client, F_SETFD, FD_CLOEXEC); + if (error) err(EX_IOERR, "fcntl"); spawn("pbpaste", STDOUT_FILENO, client); - uint8_t p; + char p; ssize_t peek = recv(client, &p, 1, MSG_PEEK); if (peek < 0) err(EX_IOERR, "recv"); - if (peek) { - spawn("pbcopy", STDIN_FILENO, client); - } + if (peek) spawn("pbcopy", STDIN_FILENO, client); - error = close(client); - if (error) err(EX_IOERR, "close"); + close(client); } } @@ -93,48 +95,42 @@ static int pbdClient(void) { .sin_port = htons(7062), .sin_addr = { .s_addr = htonl(0x7f000001) }, }; - int error = connect(client, (struct sockaddr *)&addr, sizeof(addr)); - if (error) err(EX_OSERR, "connect"); + if (error) err(EX_UNAVAILABLE, "connect"); return client; } -static void copy(int fdIn, int fdOut) { - char readBuf[4096]; - ssize_t readLen; - while (0 < (readLen = read(fdIn, readBuf, sizeof(readBuf)))) { - char *writeBuf = readBuf; - ssize_t writeLen; - while (0 < (writeLen = write(fdOut, writeBuf, readLen))) { - writeBuf += writeLen; - readLen -= writeLen; - } - if (writeLen < 0) err(EX_IOERR, "write"); +static void copy(int out, int in) { + char buf[4096]; + ssize_t readSize; + while (0 < (readSize = read(in, buf, sizeof(buf)))) { + ssize_t writeSize = write(out, buf, readSize); + if (writeSize < 0) err(EX_IOERR, "write(%d)", out); + if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", out); } - if (readLen < 0) err(EX_IOERR, "read"); + if (readSize < 0) err(EX_IOERR, "read(%d)", in); } static int pbcopy(void) { int client = pbdClient(); - copy(STDIN_FILENO, client); + copy(client, STDIN_FILENO); return EX_OK; } static int pbpaste(void) { int client = pbdClient(); - int error = shutdown(client, SHUT_WR); - if (error) err(EX_OSERR, "shutdown"); - copy(client, STDOUT_FILENO); + shutdown(client, SHUT_WR); + copy(STDOUT_FILENO, client); return EX_OK; } -int main(int argc __attribute((unused)), char *argv[]) { +int main(int argc UNUSED, char *argv[]) { if (!argv[0][0] || !argv[0][1]) return EX_USAGE; switch (argv[0][2]) { case 'd': return pbd(); case 'c': return pbcopy(); case 'p': return pbpaste(); + default: return EX_USAGE; } - return EX_USAGE; } |