diff --git a/.drone.yml b/.drone.yml index 841817b6e..73ae35ebd 100644 --- a/.drone.yml +++ b/.drone.yml @@ -13,7 +13,9 @@ steps: - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_STATIC=off -DUSE_GPM=on -DUSE_QRCODEGEN=on -DDFSG_BUILD=on - make -j2 + - ./notcurses-input < /dev/null - env NOTCURSES_LOGLEVEL=7 ./notcurses-input < notcurses-input + - ./notcurses-input < notcurses-input #- ./notcurses-info #- ctest --output-on-failure #- make install diff --git a/src/lib/direct.c b/src/lib/direct.c index c2d308627..96e8ca163 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -973,7 +973,11 @@ int ncdirect_stop(ncdirect* nc){ char* ncdirect_readline(ncdirect* n, const char* prompt){ const char* u7 = get_escape(&n->tcache, ESCAPE_U7); if(!u7){ // we probably *can*, but it would be a pita; screw it - logerror("can't readline without u7\n"); + logerror("can't readline without u7"); + return NULL; + } + if(n->eof){ + logerror("already got EOF"); return NULL; } if(fprintf(n->ttyfp, "%s", prompt) < 0){ @@ -1005,15 +1009,18 @@ char* ncdirect_readline(ncdirect* n, const char* prompt){ if(ni.evtype == NCTYPE_RELEASE){ continue; } - if(id == NCKEY_EOF || id == NCKEY_ENTER){ + if(id == NCKEY_EOF || id == NCKEY_ENTER || (ncinput_ctrl_p(&ni) && id == 'd')){ if(id == NCKEY_ENTER){ if(fputc('\n', n->ttyfp) < 0){ free(str); return NULL; } - }else if(wused == 1){ // NCKEY_EOF without input returns NULL - free(str); - return NULL; + }else{ + n->eof = 1; + if(wused == 1){ // NCKEY_EOF without input returns NULL + free(str); + return NULL; + } } char* ustr = ncwcsrtombs(str); free(str); diff --git a/src/lib/in.c b/src/lib/in.c index e9fa47228..2385538dd 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -2303,6 +2303,7 @@ read_inputs_nblock(inputctx* ictx){ if(!eof && ictx->stdineof){ // we hit EOF; write an event to the readiness fd mark_pipe_ready(ictx->readypipes); + pthread_cond_broadcast(&ictx->icond); } } } @@ -2380,7 +2381,9 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){ return (uint32_t)-1; } pthread_mutex_lock(&ictx->ilock); +fprintf(stderr, "IVALID: %u EOF: %u IREAD: %u\n", ictx->ivalid, ictx->stdineof, ictx->iread); while(!ictx->ivalid){ +fprintf(stderr, "WHILE IVALID: %u EOF: %u IREAD: %u\n", ictx->ivalid, ictx->stdineof, ictx->iread); if(ictx->stdineof){ pthread_mutex_unlock(&ictx->ilock); logwarn("read eof on stdin"); @@ -2391,7 +2394,9 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){ return NCKEY_EOF; } if(ts == NULL){ +fprintf(stderr, "WAITING\n"); pthread_cond_wait(&ictx->icond, &ictx->ilock); +fprintf(stderr, "DONE WAITING\n"); }else{ int r = pthread_cond_timedwait(&ictx->icond, &ictx->ilock, ts); if(r == ETIMEDOUT){ @@ -2411,6 +2416,7 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){ } } id = ictx->inputs[ictx->iread].id; +fprintf(stderr, "GOT ID 0x%08x IREAD: %u\n", id, ictx->iread); if(ni){ memcpy(ni, &ictx->inputs[ictx->iread], sizeof(*ni)); if(notcurses_ucs32_to_utf8(&ni->id, 1, (unsigned char*)ni->utf8, sizeof(ni->utf8)) < 0){ @@ -2470,7 +2476,15 @@ int notcurses_getvec(notcurses* n, const struct timespec* absdl, } uint32_t ncdirect_get(ncdirect* n, const struct timespec* absdl, ncinput* ni){ - return internal_get(n->tcache.ictx, absdl, ni); + if(n->eof){ + logerror("already got EOF"); + return -1; + } + uint32_t r = internal_get(n->tcache.ictx, absdl, ni); + if(r == NCKEY_EOF){ + n->eof = 1; + } + return r; } int get_cursor_location(inputctx* ictx, const char* u7, unsigned* y, unsigned* x){ diff --git a/src/lib/internal.h b/src/lib/internal.h index b95462bf4..5fb4893a2 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -252,6 +252,7 @@ typedef struct ncdirect { uint16_t stylemask; // current styles uint64_t flags; // copied in ncdirect_init() from param ncsharedstats stats; // stats! not as broadly used as in notcurses + unsigned eof; // have we seen EOF on stdin? } ncdirect; // Extracellular state for a cell during the render process. There is one