diff --git a/dtach.1 b/dtach.1 index 699925c..abc700e 100644 --- a/dtach.1 +++ b/dtach.1 @@ -13,6 +13,9 @@ dtach \- simple program that emulates the detach feature of screen. .br .B dtach \-n .I +.br +.B dtach \-N +.I .SH DESCRIPTION .B dtach @@ -93,6 +96,13 @@ which the specified program is executed. .B dtach does not try to attach to the newly created session, however, and exits instead. +.TP +.B \-N +Creates a new session, without attaching to it or daemonizing. A new session is +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. .PP .SS OPTIONS diff --git a/dtach.h b/dtach.h index f2f4951..059278e 100644 --- a/dtach.h +++ b/dtach.h @@ -128,7 +128,7 @@ struct packet #define EOS "\033[999H" int attach_main(int noerror); -int master_main(char **argv, int waitattach); +int master_main(char **argv, int waitattach, int dontfork); #ifdef sun #define BROKEN_MASTER diff --git a/main.c b/main.c index ade242a..4bd55c3 100644 --- a/main.c +++ b/main.c @@ -55,6 +55,7 @@ usage() " dtach -A \n" " dtach -c \n" " dtach -n \n" + " dtach -N \n" "Modes:\n" " -a\t\tAttach to the specified socket.\n" " -A\t\tAttach to the specified socket, or create it if it\n" @@ -62,6 +63,9 @@ usage() " -c\t\tCreate a new socket and run the specified command.\n" " -n\t\tCreate a new socket and run the specified command " "detached.\n" + " -N\t\tCreate a new socket and run the specified command " + "detached,\n" + "\t\t and have dtach run in the foreground.\n" "Options:\n" " -e \tSet the detach character to , defaults " "to ^\\.\n" @@ -102,7 +106,7 @@ main(int argc, char **argv) if (mode == '?') usage(); else if (mode != 'a' && mode != 'c' && mode != 'n' && - mode != 'A') + mode != 'A' && mode != 'N') { printf("%s: Invalid mode '-%c'\n", progname, mode); printf("Try '%s --help' for more information.\n", @@ -215,7 +219,7 @@ main(int argc, char **argv) dont_have_tty = 1; } - if (dont_have_tty && mode != 'n') + if (dont_have_tty && mode != 'n' && mode != 'N') { printf("%s: Attaching to a session requires a terminal.\n", progname); @@ -235,10 +239,12 @@ main(int argc, char **argv) return attach_main(0); } else if (mode == 'n') - return master_main(argv, 0); + return master_main(argv, 0, 0); + else if (mode == 'N') + return master_main(argv, 0, 1); else if (mode == 'c') { - if (master_main(argv, 1) != 0) + if (master_main(argv, 1, 0) != 0) return 1; return attach_main(0); } @@ -252,7 +258,7 @@ main(int argc, char **argv) { if (errno == ECONNREFUSED) unlink(sockname); - if (master_main(argv, 1) != 0) + if (master_main(argv, 1, 0) != 0) return 1; } return attach_main(0); diff --git a/master.c b/master.c index 62ecf10..9f51da0 100644 --- a/master.c +++ b/master.c @@ -543,7 +543,7 @@ master_process(int s, char **argv, int waitattach, int statusfd) } int -master_main(char **argv, int waitattach) +master_main(char **argv, int waitattach, int dontfork) { int fd[2] = {-1, -1}; int s; @@ -566,7 +566,16 @@ master_main(char **argv, int waitattach) /* If FD_CLOEXEC works, create a pipe and use it to report any errors ** that occur while trying to execute the program. */ - if (pipe(fd) >= 0) + if (dontfork) + { + fd[1] = dup(2); + if (fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0) + { + close(fd[1]); + fd[1] = -1; + } + } + else if (pipe(fd) >= 0) { if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0 || fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0) @@ -578,6 +587,12 @@ master_main(char **argv, int waitattach) } #endif + if (dontfork) + { + master_process(s, argv, waitattach, fd[1]); + return 0; + } + /* Fork off so we can daemonize and such */ pid = fork(); if (pid < 0)