Skip to content

Commit 35af931

Browse files
authored
Merge pull request #725 from rolandwalker/termios
save and restore TTY attributes
2 parents 73e0f77 + e59edc4 commit 35af931

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

include/tig/tig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <sys/file.h>
5454
#include <time.h>
5555
#include <fcntl.h>
56+
#include <termios.h>
5657

5758
#include <regex.h>
5859

src/display.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ static WINDOW *display_win[2];
3030
static WINDOW *display_title[2];
3131
static WINDOW *display_sep;
3232

33-
static FILE *opt_tty;
33+
struct display_tty {
34+
FILE *file;
35+
int fd;
36+
struct termios *attr;
37+
};
38+
static struct display_tty opt_tty = { NULL, -1, NULL };
3439

3540
static struct io script_io = { -1 };
3641

@@ -78,14 +83,16 @@ open_external_viewer(const char *argv[], const char *dir, bool silent, bool conf
7883
clear();
7984
refresh();
8085
endwin(); /* restore original tty modes */
86+
tcsetattr(opt_tty.fd, TCSAFLUSH, opt_tty.attr);
8187
ok = io_run_fg(argv, dir);
8288
if (confirm || !ok) {
8389
if (!ok && *notice)
8490
fprintf(stderr, "%s", notice);
8591
fprintf(stderr, "Press Enter to continue");
86-
getc(opt_tty);
87-
fseek(opt_tty, 0, SEEK_END);
92+
getc(opt_tty.file);
8893
}
94+
fseek(opt_tty.file, 0, SEEK_END);
95+
tcsetattr(opt_tty.fd, TCSAFLUSH, opt_tty.attr);
8996
set_terminal_modes();
9097
}
9198

@@ -554,6 +561,12 @@ done_display(void)
554561
endwin();
555562
}
556563
cursed = false;
564+
565+
if (opt_tty.attr) {
566+
tcsetattr(opt_tty.fd, TCSAFLUSH, opt_tty.attr);
567+
free(opt_tty.attr);
568+
opt_tty.attr = NULL;
569+
}
557570
}
558571

559572
static void
@@ -566,15 +579,32 @@ set_terminal_modes(void)
566579
leaveok(stdscr, false);
567580
}
568581

582+
static void
583+
init_tty(void)
584+
{
585+
/* open */
586+
opt_tty.file = fopen("/dev/tty", "r+");
587+
if (!opt_tty.file)
588+
die("Failed to open tty for input");
589+
opt_tty.fd = fileno(opt_tty.file);
590+
591+
/* attributes */
592+
opt_tty.attr = calloc(1, sizeof(struct termios));
593+
if (!opt_tty.attr)
594+
die("Failed allocation for tty attributes");
595+
tcgetattr(opt_tty.fd, opt_tty.attr);
596+
}
597+
569598
void
570599
init_display(void)
571600
{
572601
bool no_display = !!getenv("TIG_NO_DISPLAY");
573602
const char *term;
574603
int x, y;
575604

605+
init_tty();
606+
576607
die_callback = done_display;
577-
/* XXX: Restore tty modes and let the OS cleanup the rest! */
578608
if (atexit(done_display))
579609
die("Failed to register done_display");
580610

@@ -583,11 +613,10 @@ init_display(void)
583613
/* Leave stdin and stdout alone when acting as a pager. */
584614
FILE *out_tty;
585615

586-
opt_tty = fopen("/dev/tty", "r+");
587-
out_tty = no_display ? fopen("/dev/null", "w+") : opt_tty;
588-
if (!opt_tty || !out_tty)
589-
die("Failed to open /dev/tty");
590-
cursed = !!newterm(NULL, out_tty, opt_tty);
616+
out_tty = no_display ? fopen("/dev/null", "w+") : opt_tty.file;
617+
if (!out_tty)
618+
die("Failed to open tty for output");
619+
cursed = !!newterm(NULL, out_tty, opt_tty.file);
591620
}
592621

593622
if (!cursed)
@@ -693,7 +722,7 @@ get_input_char(void)
693722
return key.data.bytes[bytes_pos++];
694723
}
695724

696-
return getc(opt_tty);
725+
return getc(opt_tty.file);
697726
}
698727

699728
int

0 commit comments

Comments
 (0)