summary refs log tree commit diff
path: root/bin/pbd.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bin/pbd.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/bin/pbd.c b/bin/pbd.c
index 1c8e0e83..de16d7eb 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;
 }