Add dtach -p.

dtach -p copies the contents of standard input to a session.

Based on an initial patch by @johnlane.
This commit is contained in:
Ned T. Crigler 2015-07-18 13:13:09 -07:00
parent b7d5154c18
commit 087e89f7a8
5 changed files with 105 additions and 1 deletions

9
README
View File

@ -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.

View File

@ -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;
}
}
}

11
dtach.1
View File

@ -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

View File

@ -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

18
main.c
View File

@ -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;