[input] create ready pipes #2216

pull/2220/head
nick black 3 years ago committed by nick black
parent bbdbc055dd
commit 5899a71e28

@ -10,8 +10,8 @@ typedef struct nciqueue {
} nciqueue;
// a pipe on which we write upon receipt of input, so that demos
// can reliably multiplex against other fds. freebsd doesn't have
// eventfd, alas.
// can reliably multiplex against other fds. osx doesn't have
// eventfd, alas (freebsd added it in 13.0).
static int input_pipefds[2] = {-1, -1};
static pthread_t tid;

@ -1,4 +1,6 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "internal.h"
#include "in.h"
@ -170,6 +172,7 @@ typedef struct inputctx {
unsigned drain; // drain away bulk input?
ncsharedstats *stats; // stats shared with notcurses context
int readypipes[2]; // pipes[1]: poll()able fd indicating the presence of user input
struct initial_responses* initdata;
struct initial_responses* initdata_complete;
} inputctx;
@ -434,6 +437,40 @@ prep_special_keys(inputctx* ictx){
return 0;
}
static void
endpipes(int pipes[static 2]){
close(pipes[0]);
close(pipes[1]);
}
// only linux and freebsd13+ have eventfd(), so we'll fall back to pipes sigh.
static int
getpipes(int pipes[static 2]){
#ifndef __APPLE__
if(pipe2(pipes, O_CLOEXEC | O_NONBLOCK)){
logerror("couldn't get pipes (%s)\n", strerror(errno));
return -1;
}
#else
if(pipe(pipes)){
logerror("couldn't get pipes (%s)\n", strerror(errno));
return -1;
}
if(set_fd_cloexec(pipes[0], 1, NULL) || set_fd_nonblocking(pipes[0], 1, NULL)){
logerror("couldn't prep pipe[0] (%d) (%s)\n", pipes[0], strerror(errno));
endpipes(pipes);
return -1;
}
if(set_fd_cloexec(pipes[1], 1, NULL) || set_fd_nonblocking(pipes[1], 1, NULL)){
logerror("couldn't prep pipe[1] (%d) (%s)\n", pipes[1], strerror(errno));
endpipes(pipes);
return -1;
}
// FIXME what to do on windows?
#endif
return 0;
}
static inline inputctx*
create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin,
ncsharedstats* stats, unsigned drain,
@ -450,34 +487,37 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin,
if(pthread_cond_init(&i->ccond, NULL) == 0){
if((i->stdinfd = fileno(infp)) >= 0){
if( (i->initdata = malloc(sizeof(*i->initdata))) ){
i->inputescapes = NULL;
if(prep_special_keys(i) == 0){
if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){
i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp);
memset(i->initdata, 0, sizeof(*i->initdata));
i->state = i->stringstate = STATE_NULL;
i->iread = i->iwrite = i->ivalid = 0;
i->cread = i->cwrite = i->cvalid = 0;
i->initdata_complete = NULL;
i->stats = stats;
i->ti = ti;
i->stdineof = 0;
if(getpipes(i->readypipes) == 0){
i->inputescapes = NULL;
if(prep_special_keys(i) == 0){
if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){
i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp);
memset(i->initdata, 0, sizeof(*i->initdata));
i->state = i->stringstate = STATE_NULL;
i->iread = i->iwrite = i->ivalid = 0;
i->cread = i->cwrite = i->cvalid = 0;
i->initdata_complete = NULL;
i->stats = stats;
i->ti = ti;
i->stdineof = 0;
#ifdef __MINGW64__
i->stdinhandle = ti->inhandle;
i->stdinhandle = ti->inhandle;
#endif
i->ibufvalid = 0;
i->linesigs = linesigs_enabled;
i->tbufvalid = 0;
i->midescape = 0;
i->numeric = 0;
i->stridx = 0;
i->runstring[i->stridx] = '\0';
i->lmargin = lmargin;
i->tmargin = tmargin;
i->drain = drain;
logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd);
return i;
i->ibufvalid = 0;
i->linesigs = linesigs_enabled;
i->tbufvalid = 0;
i->midescape = 0;
i->numeric = 0;
i->stridx = 0;
i->runstring[i->stridx] = '\0';
i->lmargin = lmargin;
i->tmargin = tmargin;
i->drain = drain;
logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd);
return i;
}
}
endpipes(i->readypipes);
}
input_free_esctrie(&i->inputescapes);
}
@ -521,6 +561,7 @@ free_inputctx(inputctx* i){
free(i->initdata_complete->version);
free(i->initdata_complete);
}
endpipes(i->readypipes);
free(i->inputs);
free(i->csrs);
free(i);
@ -1995,7 +2036,7 @@ int stop_inputlayer(tinfo* ti){
}
int inputready_fd(const inputctx* ictx){
return ictx->stdinfd;
return ictx->readypipes[1];
}
static inline uint32_t

Loading…
Cancel
Save