diff --git a/src/lib/direct.c b/src/lib/direct.c index 4ef7fd79f..eeef64f7a 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -617,20 +617,6 @@ int ncdirect_printf_aligned(ncdirect* n, int y, ncalign_e align, const char* fmt return ret; } -int get_controlling_tty(FILE* ttyfp){ - int fd = fileno(ttyfp); - if(fd > 0 && isatty(fd)){ - if((fd = dup(fd)) >= 0){ - return fd; - } - } - char cbuf[L_ctermid + 1]; - if(ctermid(cbuf) == NULL){ - return -1; - } - return open(cbuf, O_RDWR | O_CLOEXEC); -} - static int ncdirect_stop_minimal(void* vnc){ ncdirect* nc = vnc; @@ -687,7 +673,7 @@ ncdirect* ncdirect_core_init(const char* termtype, FILE* outfp, uint64_t flags){ return NULL; } // we don't need a controlling tty for everything we do; allow a failure here - if((ret->ctermfd = get_controlling_tty(ret->ttyfp)) >= 0){ + if((ret->ctermfd = get_tty_fd(NULL, ret->ttyfp)) >= 0){ if(tcgetattr(ret->ctermfd, &ret->tpreserved)){ fprintf(stderr, "Couldn't preserve terminal state for %d (%s)\n", ret->ctermfd, strerror(errno)); goto err; diff --git a/src/lib/fd.c b/src/lib/fd.c index b88c413de..e7007a149 100644 --- a/src/lib/fd.c +++ b/src/lib/fd.c @@ -455,3 +455,35 @@ int ncsubproc_destroy(ncsubproc* n){ ncplane* ncsubproc_plane(ncsubproc* n){ return n->nfp->ncp; } + +// if ttyfp is a tty, return a file descriptor extracted from it. otherwise, +// try to get the controlling terminal. otherwise, return -1. +int get_tty_fd(notcurses* nc, FILE* ttyfp){ + int fd = -1; + if(ttyfp){ + if((fd = fileno(ttyfp)) < 0){ + logwarn(nc, "No file descriptor was available in outfp %p\n", ttyfp); + }else{ + if(isatty(fd)){ + fd = dup(fd); + }else{ + loginfo(nc, "File descriptor %d was not a TTY\n", fd); + fd = -1; + } + } + } + if(fd < 0){ + fd = open("/dev/tty", O_RDWR | O_CLOEXEC); + if(fd < 0){ + loginfo(nc, "Error opening /dev/tty (%s)\n", strerror(errno)); + }else{ + if(!isatty(fd)){ + loginfo(nc, "File descriptor for /dev/tty (%d) is not actually a TTY\n", fd); + close(fd); + fd = -1; + } + } + } + loginfo(nc, "Returning TTY fd %d\n", fd); + return fd; +} diff --git a/src/lib/internal.h b/src/lib/internal.h index c96930565..01042f647 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1342,6 +1342,8 @@ int cbreak_mode(int ttyfd, const struct termios* tpreserved); int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate); +int get_tty_fd(notcurses* nc, FILE* ttyfp); + // Given the four channels arguments, verify that: // // - if any is default foreground, all are default foreground diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 36ef00fbe..dcdc211ba 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -865,38 +865,6 @@ void init_lang(struct notcurses* nc){ } } -// if ttyfp is a tty, return a file descriptor extracted from it. otherwise, -// try to get the controlling terminal. otherwise, return -1. -static int -get_tty_fd(notcurses* nc, FILE* ttyfp){ - int fd = -1; - if(ttyfp){ - if((fd = fileno(ttyfp)) < 0){ - logwarn(nc, "No file descriptor was available in outfp %p\n", ttyfp); - }else{ - if(isatty(fd)){ - fd = dup(fd); - }else{ - loginfo(nc, "File descriptor %d was not a TTY\n", fd); - fd = -1; - } - } - } - if(fd < 0){ - fd = open("/dev/tty", O_RDWR | O_CLOEXEC); - if(fd < 0){ - loginfo(nc, "Error opening /dev/tty (%s)\n", strerror(errno)); - }else{ - if(!isatty(fd)){ - loginfo(nc, "File descriptor for /dev/tty (%d) is not actually a TTY\n", fd); - close(fd); - fd = -1; - } - } - } - return fd; -} - int ncinputlayer_init(ncinputlayer* nilayer, FILE* infp){ setbuffer(infp, NULL, 0); nilayer->inputescapes = NULL; diff --git a/src/tests/fade.cpp b/src/tests/fade.cpp index 4af5fd9ef..4d960c949 100644 --- a/src/tests/fade.cpp +++ b/src/tests/fade.cpp @@ -59,11 +59,11 @@ TEST_CASE("Fade") { } SUBCASE("FadeOut") { - CHECK(0 == notcurses_render(nc_)); struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 250000000; CHECK(0 == ncplane_fadeout(n_, &ts, nullptr, nullptr)); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("FadeIn") { @@ -71,14 +71,15 @@ TEST_CASE("Fade") { ts.tv_sec = 0; ts.tv_nsec = 250000000; CHECK(0 == ncplane_fadein(n_, &ts, nullptr, nullptr)); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("FadeOutAbort") { - CHECK(0 == notcurses_render(nc_)); struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 250000000; CHECK(0 < ncplane_fadeout(n_, &ts, fadeaborter, nullptr)); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("FadeInAbort") { @@ -86,6 +87,7 @@ TEST_CASE("Fade") { ts.tv_sec = 0; ts.tv_nsec = 250000000; CHECK(0 < ncplane_fadein(n_, &ts, fadeaborter, nullptr)); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("Pulse") { @@ -100,6 +102,7 @@ TEST_CASE("Fade") { struct timespec pulsestart; clock_gettime(CLOCK_MONOTONIC, &pulsestart); CHECK(0 < ncplane_pulse(n_, &ts, pulser, &pulsestart)); + CHECK(0 == notcurses_render(nc_)); } // drive fadeout with the more flexible api @@ -112,6 +115,7 @@ TEST_CASE("Fade") { CHECK(0 == ncplane_fadeout_iteration(n_, nctx, i, nullptr, nullptr)); } ncfadectx_free(nctx); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("FadeOutFlexibleAbort") { @@ -123,6 +127,7 @@ TEST_CASE("Fade") { CHECK(0 < ncplane_fadeout_iteration(n_, nctx, i, fadeaborter, nullptr)); } ncfadectx_free(nctx); + CHECK(0 == notcurses_render(nc_)); } // drive fadein with the more flexible api @@ -135,6 +140,7 @@ TEST_CASE("Fade") { CHECK(0 == ncplane_fadein_iteration(n_, nctx, i, nullptr, nullptr)); } ncfadectx_free(nctx); + CHECK(0 == notcurses_render(nc_)); } SUBCASE("FadeInFlexibleAbort") { @@ -146,6 +152,7 @@ TEST_CASE("Fade") { CHECK(0 < ncplane_fadein_iteration(n_, nctx, i, fadeaborter, nullptr)); } ncfadectx_free(nctx); + CHECK(0 == notcurses_render(nc_)); } CHECK(0 == notcurses_stop(nc_));