summaryrefslogtreecommitdiff
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
parentb7d5154c18cb57dd5680114315fbc4175cf1ea26 (diff)
Add dtach -p.
dtach -p copies the contents of standard input to a session. Based on an initial patch by @johnlane.
-rw-r--r--README9
-rw-r--r--attach.c67
-rw-r--r--dtach.111
-rw-r--r--dtach.h1
-rw-r--r--main.c18
5 files changed, 105 insertions, 1 deletions
diff --git a/README b/README
index fc3dc08..f732b8b 100644
--- a/README
+++ b/README
@@ -66,6 +66,15 @@ will likely encounter problems if your terminals have different window
sizes. Pressing ^L (Ctrl-L) will reset the window size of the program to
match the current terminal.
+dtach also has a mode that copies the contents of standard input to a session.
+For example:
+
+ $ echo -ne 'cd /var/log\nls -l\n' | dtach -p /tmp/foozle
+
+The contents are sent verbatim including any embedded control characters (e.g.
+the newline characters in the above example), and dtach will not scan the
+input for a detach character.
+
3. DETACHING FROM THE SESSION
By default, dtach scans the keyboard input looking for the detach character.
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;
+ }
+ }
+}
diff --git a/dtach.1 b/dtach.1
index abc700e..6819358 100644
--- a/dtach.1
+++ b/dtach.1
@@ -16,6 +16,9 @@ dtach \- simple program that emulates the detach feature of screen.
.br
.B dtach \-N
.I <socket> <options> <command...>
+.br
+.B dtach \-p
+.I <socket>
.SH DESCRIPTION
.B dtach
@@ -103,6 +106,14 @@ created in which the specified program is executed.
.B dtach
does not try to attach to the newly created session, however, and will stay
in the foreground until the program exits.
+.TP
+.B \-p
+Copies the contents of standard input to a session.
+.B dtach
+connects to the session specified by
+.IR <socket> ,
+copies the contents of standard input to the session, and then exits. dtach
+will not scan the input for a detach character.
.PP
.SS OPTIONS
diff --git a/dtach.h b/dtach.h
index 059278e..88946a0 100644
--- a/dtach.h
+++ b/dtach.h
@@ -129,6 +129,7 @@ struct packet
int attach_main(int noerror);
int master_main(char **argv, int waitattach, int dontfork);
+int push_main(void);
#ifdef sun
#define BROKEN_MASTER
diff --git a/main.c b/main.c
index 4bd55c3..0f9f459 100644
--- a/main.c
+++ b/main.c
@@ -56,6 +56,7 @@ usage()
" dtach -c <socket> <options> <command...>\n"
" dtach -n <socket> <options> <command...>\n"
" dtach -N <socket> <options> <command...>\n"
+ " dtach -p <socket>\n"
"Modes:\n"
" -a\t\tAttach to the specified socket.\n"
" -A\t\tAttach to the specified socket, or create it if it\n"
@@ -66,6 +67,8 @@ usage()
" -N\t\tCreate a new socket and run the specified command "
"detached,\n"
"\t\t and have dtach run in the foreground.\n"
+ " -p\t\tCopy the contents of standard input to the specified\n"
+ "\t\t socket.\n"
"Options:\n"
" -e <char>\tSet the detach character to <char>, defaults "
"to ^\\.\n"
@@ -106,7 +109,7 @@ main(int argc, char **argv)
if (mode == '?')
usage();
else if (mode != 'a' && mode != 'c' && mode != 'n' &&
- mode != 'A' && mode != 'N')
+ mode != 'A' && mode != 'N' && mode != 'p')
{
printf("%s: Invalid mode '-%c'\n", progname, mode);
printf("Try '%s --help' for more information.\n",
@@ -133,6 +136,19 @@ main(int argc, char **argv)
sockname = *argv;
++argv; --argc;
+ if (mode == 'p')
+ {
+ if (argc > 0)
+ {
+ printf("%s: Invalid number of arguments.\n",
+ progname);
+ printf("Try '%s --help' for more information.\n",
+ progname);
+ return 1;
+ }
+ return push_main();
+ }
+
while (argc >= 1 && **argv == '-')
{
char *p;