diff --git a/attach.c b/attach.c index 034e277..f31d789 100644 --- a/attach.c +++ b/attach.c @@ -39,9 +39,10 @@ static void restore_term(void) { tcsetattr(0, TCSADRAIN, &orig_term); - - /* Make cursor visible. Assumes VT100. */ - printf("\033[?25h"); + + /* Reset terminal and make cursor visible. Assumes VT100. */ + printf("\033[0m\033[?25h"); + fflush(stdout); } @@ -89,9 +90,9 @@ die(int sig) { /* Print a nice pretty message for some things. */ if (sig == SIGHUP || sig == SIGINT) - printf(EOS "\r\n[detached]\r\n"); + printf("%s[detached]\r\n", clear_csi_data()); else - printf(EOS "\r\n[got signal %d - dying]\r\n", sig); + printf("%s[got signal %d - dying]\r\n", clear_csi_data(), sig); exit(1); } @@ -116,7 +117,7 @@ process_kbd(int s, struct packet *pkt) /* And suspend... */ tcsetattr(0, TCSADRAIN, &orig_term); - printf(EOS "\r\n"); + printf("%s", clear_csi_data()); kill(getpid(), SIGTSTP); tcsetattr(0, TCSADRAIN, &cur_term); @@ -134,7 +135,7 @@ process_kbd(int s, struct packet *pkt) /* Detach char? */ else if (pkt->u.buf[0] == detach_char) { - printf(EOS "\r\n[detached]\r\n"); + printf("%s[detached]\r\n", clear_csi_data()); exit(0); } /* Just in case something pukes out. */ @@ -215,7 +216,14 @@ attach_main(int noerror) tcsetattr(0, TCSADRAIN, &cur_term); /* Clear the screen. This assumes VT100. */ - write(1, "\33[H\33[J", 6); + if (clear_method == CLEAR_NONE) + if (!quiet) + write(1, "\r\n", 2); + else { + // NOTE: Nothing to do in this case! + } + else + write(1, "\033c", 2); /* Tell the master that we want to attach. */ memset(&pkt, 0, sizeof(struct packet)); @@ -239,7 +247,7 @@ attach_main(int noerror) n = select(s + 1, &readfds, NULL, NULL, NULL); if (n < 0 && errno != EINTR && errno != EAGAIN) { - printf(EOS "\r\n[select failed]\r\n"); + printf("%s[select failed]\r\n", clear_csi_data()); exit(1); } @@ -250,13 +258,13 @@ attach_main(int noerror) if (len == 0) { - printf(EOS "\r\n[EOF - dtach terminating]" - "\r\n"); + if (!quiet) + printf("%s[EOF - dtach terminating]\r\n", clear_csi_data()); exit(0); } else if (len < 0) { - printf(EOS "\r\n[read returned an error]\r\n"); + printf("%s[read returned an error]\r\n", clear_csi_data()); exit(1); } /* Send the data to the terminal. */ diff --git a/dtach.h b/dtach.h index d0ba87e..a6a5fe2 100644 --- a/dtach.h +++ b/dtach.h @@ -82,7 +82,7 @@ #endif extern char *progname, *sockname; -extern int detach_char, no_suspend, redraw_method; +extern int detach_char, no_suspend, redraw_method, clear_method, quiet; extern struct termios orig_term; extern int dont_have_tty; @@ -103,6 +103,13 @@ enum REDRAW_WINCH = 3, }; +enum +{ + CLEAR_UNSPEC = 0, + CLEAR_NONE = 1, + CLEAR_MOVE = 2, +}; + /* The client to master protocol. */ struct packet { @@ -124,13 +131,12 @@ struct packet */ #define BUFSIZE 4096 -/* This hopefully moves to the bottom of the screen */ -#define EOS "\033[999H" - int attach_main(int noerror); int master_main(char **argv, int waitattach, int dontfork); int push_main(void); +char const * clear_csi_data(); + #ifdef sun #define BROKEN_MASTER #endif diff --git a/main.c b/main.c index 5fd7bcc..7b013aa 100644 --- a/main.c +++ b/main.c @@ -37,6 +37,9 @@ int detach_char = '\\' - 64; int no_suspend; /* The default redraw method. Initially set to unspecified. */ int redraw_method = REDRAW_UNSPEC; +/* The default clear method. Initially set to unspecified. */ +int clear_method = CLEAR_UNSPEC; +int quiet = 0; /* ** The original terminal settings. Shared between the master and attach @@ -78,7 +81,12 @@ usage() "\t\t none: Don't redraw at all.\n" "\t\t ctrl_l: Send a Ctrl L character to the program.\n" "\t\t winch: Send a WINCH signal to the program.\n" + " -R \tSet the clear method to . The " + "valid methods are:\n" + "\t\t none: Don't clear at all.\n" + "\t\t move: Move to last line (default behaviour).\n" " -z\t\tDisable processing of the suspend key.\n" + " -q\t\tDisable printing of additional messages.\n" "\nReport any bugs to <" PACKAGE_BUGREPORT ">.\n", PACKAGE_VERSION, __DATE__, __TIME__); exit(0); @@ -153,12 +161,19 @@ main(int argc, char **argv) { char *p; + if (strcmp(argv[0], "--") == 0) { + ++argv; --argc; + break; + } + for (p = argv[0] + 1; *p; ++p) { if (*p == 'E') detach_char = -1; else if (*p == 'z') no_suspend = 1; + else if (*p == 'q') + quiet = 1; else if (*p == 'e') { ++argv; --argc; @@ -208,6 +223,31 @@ main(int argc, char **argv) } break; } + else if (*p == 'R') + { + ++argv; --argc; + if (argc < 1) + { + printf("%s: No clear method " + "specified.\n", progname); + printf("Try '%s --help' for more " + "information.\n", progname); + return 1; + } + if (strcmp(argv[0], "none") == 0) + clear_method = CLEAR_NONE; + else if (strcmp(argv[0], "move") == 0) + clear_method = CLEAR_MOVE; + else + { + printf("%s: Invalid clear method " + "specified.\n", progname); + printf("Try '%s --help' for more " + "information.\n", progname); + return 1; + } + break; + } else { printf("%s: Invalid option '-%c'\n", @@ -282,3 +322,18 @@ main(int argc, char **argv) } return 0; } + + +char const * clear_csi_data() +{ + switch (clear_method) { + case CLEAR_NONE : + return "\r\n"; + case CLEAR_UNSPEC : + case CLEAR_MOVE : + default : + /* This hopefully moves to the bottom of the screen */ + return "\033[999H\r\n"; + } +} + diff --git a/master.c b/master.c index b136f03..f644856 100644 --- a/master.c +++ b/master.c @@ -130,7 +130,7 @@ init_pty(char **argv, int statusfd) if (statusfd != -1) dup2(statusfd, 1); else - printf(EOS "\r\n"); + printf("%s", clear_csi_data()); printf("%s: could not execute %s: %s\r\n", progname, *argv, strerror(errno));