summaryrefslogtreecommitdiff
path: root/attach.c
diff options
context:
space:
mode:
authorNed T. Crigler <crigler@users.sourceforge.net>2015-07-18 13:13:09 -0700
committerNed T. Crigler <crigler@users.sourceforge.net>2015-07-18 13:13:09 -0700
commit087e89f7a8fecba3e8d276ab9808f10e6077784b (patch)
tree7c0e6148ec590c989632416031711437b1e626bb /attach.c
parentb7d5154c18cb57dd5680114315fbc4175cf1ea26 (diff)
Add dtach -p.
dtach -p copies the contents of standard input to a session. Based on an initial patch by @johnlane.
Diffstat (limited to 'attach.c')
-rw-r--r--attach.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/attach.c b/attach.c
index 45788e2..c01e86d 100644
--- a/attach.c
+++ b/attach.c
@@ -292,3 +292,70 @@ attach_main(int noerror)
}
return 0;
}
+
+int
+push_main()
+{
+ struct packet pkt;
+ int s;
+
+ /* Attempt to open the socket. */
+ s = connect_socket(sockname);
+ if (s < 0 && errno == ENAMETOOLONG)
+ {
+ char *slash = strrchr(sockname, '/');
+
+ /* Try to shorten the socket's path name by using chdir. */
+ if (slash)
+ {
+ int dirfd = open(".", O_RDONLY);
+
+ if (dirfd >= 0)
+ {
+ *slash = '\0';
+ if (chdir(sockname) >= 0)
+ {
+ s = connect_socket(slash + 1);
+ fchdir(dirfd);
+ }
+ *slash = '/';
+ close(dirfd);
+ }
+ }
+ }
+ if (s < 0)
+ {
+ printf("%s: %s: %s\n", progname, sockname, strerror(errno));
+ return 1;
+ }
+
+ /* Set some signals. */
+ signal(SIGPIPE, SIG_IGN);
+
+ /* Push the contents of standard input to the socket. */
+ pkt.type = MSG_PUSH;
+ for (;;)
+ {
+ ssize_t len;
+
+ memset(pkt.u.buf, 0, sizeof(pkt.u.buf));
+ len = read(0, pkt.u.buf, sizeof(pkt.u.buf));
+
+ if (len == 0)
+ return 0;
+ else if (len < 0)
+ {
+ printf("%s: %s: %s\n", progname, sockname,
+ strerror(errno));
+ return 1;
+ }
+
+ pkt.len = len;
+ if (write(s, &pkt, sizeof(struct packet)) < 0)
+ {
+ printf("%s: %s: %s\n", progname, sockname,
+ strerror(errno));
+ return 1;
+ }
+ }
+}