deal with broken ttys on MS Windows

The tty device timestamps on MS Windows aren't usable because they're always
the current time. So fish can't use them to decide if the entire prompt needs
to be repainted.

Fixes #2859
This commit is contained in:
Kurtis Rader
2016-06-17 13:08:25 -07:00
parent f04644f749
commit 8e21d5de92
4 changed files with 52 additions and 2 deletions

View File

@@ -407,6 +407,36 @@ static int fish_parse_opt(int argc, char **argv, std::vector<std::string> *cmds)
return optind;
}
/// Various things we need to initialize at run-time that don't really fit any of the other init
/// routines.
static void misc_init() {
#ifdef OS_IS_CYGWIN
// MS Windows tty devices do not have either a read or write timestamp. Those respective fields
// of `struct stat` are always the current time. Which means we can't use them. So we assume no
// external program has written to the terminal behind our back. This makes multiline prompts
// usable. See issue #2859.
has_working_tty_timestamps = false;
#else
// This covers Windows Subsystem for Linux (WSL).
int fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
if (fd != -1) {
const char *magic_suffix = "Microsoft";
int len_magic_suffix = strlen(magic_suffix);
char osrelease[128] = {0};
int len_osrelease = read(fd, osrelease, sizeof(osrelease) - 1);
if (osrelease[len_osrelease - 1] == '\n') {
osrelease[len_osrelease - 1] = '\0';
len_osrelease--;
}
if (len_osrelease >= len_magic_suffix &&
strcmp(magic_suffix, osrelease + len_osrelease - len_magic_suffix) == 0) {
has_working_tty_timestamps = false;
}
close(fd);
}
#endif // OS_IS_MS_WINDOWS
}
int main(int argc, char **argv) {
int res = 1;
int my_optind = 0;
@@ -452,6 +482,7 @@ int main(int argc, char **argv) {
history_init();
// For set_color to support term256 in config.fish (issue #1022).
update_fish_color_support();
misc_init();
parser_t &parser = parser_t::principal_parser();