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:
parent
b7d5154c18
commit
087e89f7a8
9
README
9
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
|
sizes. Pressing ^L (Ctrl-L) will reset the window size of the program to
|
||||||
match the current terminal.
|
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
|
3. DETACHING FROM THE SESSION
|
||||||
|
|
||||||
By default, dtach scans the keyboard input looking for the detach character.
|
By default, dtach scans the keyboard input looking for the detach character.
|
||||||
|
|
|
||||||
67
attach.c
67
attach.c
|
|
@ -292,3 +292,70 @@ attach_main(int noerror)
|
||||||
}
|
}
|
||||||
return 0;
|
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
11
dtach.1
|
|
@ -16,6 +16,9 @@ dtach \- simple program that emulates the detach feature of screen.
|
||||||
.br
|
.br
|
||||||
.B dtach \-N
|
.B dtach \-N
|
||||||
.I <socket> <options> <command...>
|
.I <socket> <options> <command...>
|
||||||
|
.br
|
||||||
|
.B dtach \-p
|
||||||
|
.I <socket>
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B dtach
|
.B dtach
|
||||||
|
|
@ -103,6 +106,14 @@ created in which the specified program is executed.
|
||||||
.B dtach
|
.B dtach
|
||||||
does not try to attach to the newly created session, however, and will stay
|
does not try to attach to the newly created session, however, and will stay
|
||||||
in the foreground until the program exits.
|
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
|
.PP
|
||||||
.SS OPTIONS
|
.SS OPTIONS
|
||||||
|
|
|
||||||
1
dtach.h
1
dtach.h
|
|
@ -129,6 +129,7 @@ struct packet
|
||||||
|
|
||||||
int attach_main(int noerror);
|
int attach_main(int noerror);
|
||||||
int master_main(char **argv, int waitattach, int dontfork);
|
int master_main(char **argv, int waitattach, int dontfork);
|
||||||
|
int push_main(void);
|
||||||
|
|
||||||
#ifdef sun
|
#ifdef sun
|
||||||
#define BROKEN_MASTER
|
#define BROKEN_MASTER
|
||||||
|
|
|
||||||
18
main.c
18
main.c
|
|
@ -56,6 +56,7 @@ usage()
|
||||||
" dtach -c <socket> <options> <command...>\n"
|
" dtach -c <socket> <options> <command...>\n"
|
||||||
" dtach -n <socket> <options> <command...>\n"
|
" dtach -n <socket> <options> <command...>\n"
|
||||||
" dtach -N <socket> <options> <command...>\n"
|
" dtach -N <socket> <options> <command...>\n"
|
||||||
|
" dtach -p <socket>\n"
|
||||||
"Modes:\n"
|
"Modes:\n"
|
||||||
" -a\t\tAttach to the specified socket.\n"
|
" -a\t\tAttach to the specified socket.\n"
|
||||||
" -A\t\tAttach to the specified socket, or create it if it\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 "
|
" -N\t\tCreate a new socket and run the specified command "
|
||||||
"detached,\n"
|
"detached,\n"
|
||||||
"\t\t and have dtach run in the foreground.\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"
|
"Options:\n"
|
||||||
" -e <char>\tSet the detach character to <char>, defaults "
|
" -e <char>\tSet the detach character to <char>, defaults "
|
||||||
"to ^\\.\n"
|
"to ^\\.\n"
|
||||||
|
|
@ -106,7 +109,7 @@ main(int argc, char **argv)
|
||||||
if (mode == '?')
|
if (mode == '?')
|
||||||
usage();
|
usage();
|
||||||
else if (mode != 'a' && mode != 'c' && mode != 'n' &&
|
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("%s: Invalid mode '-%c'\n", progname, mode);
|
||||||
printf("Try '%s --help' for more information.\n",
|
printf("Try '%s --help' for more information.\n",
|
||||||
|
|
@ -133,6 +136,19 @@ main(int argc, char **argv)
|
||||||
sockname = *argv;
|
sockname = *argv;
|
||||||
++argv; --argc;
|
++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 == '-')
|
while (argc >= 1 && **argv == '-')
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue