You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.4 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <stddef.h>
  5. #include <unistd.h>
  6. #include <sys/socket.h>
  7. #include <sys/un.h>
  8. int main(int argc, char *argv[]) {
  9. char buf[1024];
  10. ssize_t r;
  11. if (argc != 2) {
  12. fprintf(stderr, "Write to and read from a Unix domain socket.\n\nUsage: %s <socket>\n", argv[0]);
  13. return 1;
  14. }
  15. size_t addrlen = strlen(argv[1]);
  16. /* Allocate enough space for arbitrary-length paths */
  17. char addrbuf[offsetof(struct sockaddr_un, sun_path) + addrlen + 1];
  18. memset(addrbuf, 0, sizeof(addrbuf));
  19. struct sockaddr_un *addr = (struct sockaddr_un *)addrbuf;
  20. addr->sun_family = AF_UNIX;
  21. memcpy(addr->sun_path, argv[1], addrlen+1);
  22. int fd = socket(AF_UNIX, SOCK_STREAM, 0);
  23. if (fd < 0) {
  24. fprintf(stderr, "Failed to create socket: %s\n", strerror(errno));
  25. return 1;
  26. }
  27. if (connect(fd, (struct sockaddr*)addr, sizeof(addrbuf)) < 0) {
  28. fprintf(stderr, "Can't connect to `%s': %s\n", argv[1], strerror(errno));
  29. return 1;
  30. }
  31. /* Check if stdin refers to a terminal */
  32. if (!isatty(fileno(stdin))) {
  33. /* Read from stdin and write to socket */
  34. while (0 < (r = fread(buf, 1, sizeof(buf), stdin))) {
  35. send(fd, buf, r, 0);
  36. }
  37. }
  38. /* Read from socket and write to stdout */
  39. while (1) {
  40. r = recv(fd, buf, sizeof(buf), 0);
  41. if (r < 0) {
  42. fprintf(stderr, "read: %s\n", strerror(errno));
  43. return 1;
  44. }
  45. if (r == 0)
  46. return 0;
  47. fwrite(buf, r, 1, stdout);
  48. }
  49. return 0;
  50. }