sockread: cleanup code and allow arguments
authorMoritz Warning <moritzwarning@web.de>
Mon, 20 Nov 2023 19:37:36 +0000 (20:37 +0100)
committerTianling Shen <cnsztl@gmail.com>
Wed, 22 Nov 2023 14:39:17 +0000 (22:39 +0800)
* cleanup code style
* allow arguments to be passed from the command line

Signed-off-by: Moritz Warning <moritzwarning@web.de>
utils/sockread/Makefile
utils/sockread/src/main.c

index 52daf82b1fec096ad22ec9c73dce38ae768c0374..305c56d7888e9d5f8af6a7d87bdea28cc73dacb6 100644 (file)
@@ -4,8 +4,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sockread
-PKG_VERSION:=1.0
-PKG_RELEASE:=2
+PKG_VERSION:=1.1
+PKG_RELEASE:=1
 PKG_LICENSE:=CC0-1.0
 
 include $(INCLUDE_DIR)/package.mk
@@ -13,13 +13,12 @@ include $(INCLUDE_DIR)/package.mk
 define Package/sockread
        SECTION:=utils
        CATEGORY:=Utilities
-       TITLE:=sockread
+       TITLE:=Unix domain sockets utility
        MAINTAINER:=Moritz Warning <moritzwarning@web.de>
 endef
 
 define Package/sockread/description
-       sockread writes and reads data from a Unix domain socket
-       represented as a special file on the file system.
+       Command line utility to read and write to Unix domain sockets.
 endef
 
 define Build/Prepare
index c685bce71b89ce4eb9f9156bca6596f74bb85812..b6d0713a96c9567a54fb5090c03a48f25fe768c0 100644 (file)
@@ -7,57 +7,65 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-int main(int argc, char *argv[]) {
-       char buf[1024];
-       ssize_t r;
-
-       if (argc != 2) {
-               fprintf(stderr, "Write to and read from a Unix domain socket.\n\nUsage: %s <socket>\n", argv[0]);
-               return 1;
-       }
-
-       size_t addrlen = strlen(argv[1]);
-
-       /* Allocate enough space for arbitrary-length paths */
-       char addrbuf[offsetof(struct sockaddr_un, sun_path) + addrlen + 1];
-       memset(addrbuf, 0, sizeof(addrbuf));
-
-       struct sockaddr_un *addr = (struct sockaddr_un *)addrbuf;
-       addr->sun_family = AF_UNIX;
-       memcpy(addr->sun_path, argv[1], addrlen+1);
-
-       int fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (fd < 0) {
-               fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
-               return 1;
-       }
-
-       if (connect(fd, (struct sockaddr*)addr, sizeof(addrbuf)) < 0) {
-               fprintf(stderr, "Can't connect to `%s': %s\n", argv[1], strerror(errno));
-               return 1;
-       }
-
-       /* Check if stdin refers to a terminal */
-       if (!isatty(fileno(stdin))) {
-               /* Read from stdin and write to socket */
-               while (0 < (r = fread(buf, 1, sizeof(buf), stdin))) {
-                       send(fd, buf, r, 0);
-               }
-       }
-
-       /* Read from socket and write to stdout */
-       while (1) {
-               r = recv(fd, buf, sizeof(buf), 0);
-               if (r < 0) {
-                       fprintf(stderr, "read: %s\n", strerror(errno));
-                       return 1;
-               }
-
-               if (r == 0)
-                       return 0;
-
-               fwrite(buf, r, 1, stdout);
-       }
-
-       return 0;
+const char *usage =
+    "Write to and read from a Unix domain socket.\n"
+    "Add commands to send as arguments or pass by pipe.\n"
+    "\n"
+    "Usage: sockread <path> [<commands>]\n";
+
+int main(int argc, char *argv[])
+{
+    char buffer[1024];
+    ssize_t r;
+
+    if (argc < 2) {
+        fprintf(stderr, "%s", usage);
+        return EXIT_FAILURE;
+    }
+
+    struct sockaddr_un address = {0};
+    address.sun_family = AF_UNIX;
+    strcpy((char*) &address.sun_path, argv[1]);
+
+    int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (sock < 0) {
+        fprintf(stderr, "socket() %s\n", strerror(errno));
+        return EXIT_FAILURE;
+    }
+
+    if (connect(sock, (struct sockaddr*)&address, sizeof(address)) < 0) {
+        fprintf(stderr, "connect() %s\n", strerror(errno));
+        return EXIT_FAILURE;
+    }
+
+    /* Check if stdin refers to a terminal */
+    if (!isatty(fileno(stdin))) {
+        /* Read from stdin and write to socket */
+        while (0 < (r = fread(buffer, 1, sizeof(buffer), stdin))) {
+            send(sock, buffer, r, 0);
+        }
+    } else {
+        for (size_t i = 2; i < argc; i++) {
+            if (i > 2) {
+                send(sock, " ", 1, 0);
+            }
+            send(sock, argv[i], strlen(argv[i]), 0);
+        }
+    }
+
+    /* Read from socket and write to stdout */
+    while (1) {
+        r = recv(sock, buffer, sizeof(buffer), 0);
+        if (r < 0) {
+            fprintf(stderr, "recv() %s\n", strerror(errno));
+            return EXIT_FAILURE;
+        }
+
+        if (r == 0)
+            break;
+
+        fwrite(buffer, r, 1, stdout);
+    }
+
+    return EXIT_SUCCESS;
 }