diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 0b93f21af..af7c8bffe 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -3,16 +3,29 @@ - EPICS Base R3.14.12.5 Release Notes + EPICS Base R3.14.12.6 Release Notes +

EPICS Base Release 3.14.12.6

+ +

Changes between 3.14.12.5 and 3.14.12.6

+ + + +

Clean up after GNU readline()

+ +

If EPICS Base is built with readline support, any IOC that calls epicsExit() +from a thread other than the main thread is likely to leave the user's terminal +in a weird state, requiring the user to run something like 'stty sane' to clean +it up. This release patches the readline support code to clean up automatically +by registering an epicsAtExit() routine.

+ +

EPICS Base Release 3.14.12.5

Changes between 3.14.12.4 and 3.14.12.5

- -

aoRecord raw conversion overflows

The ao record type now checks converted raw values and limits them to the diff --git a/src/libCom/osi/os/default/epicsReadline.c b/src/libCom/osi/os/default/epicsReadline.c index 6c442e376..1d7d9c1d5 100644 --- a/src/libCom/osi/os/default/epicsReadline.c +++ b/src/libCom/osi/os/default/epicsReadline.c @@ -14,6 +14,7 @@ #define epicsExportSharedSymbols #include "envDefs.h" +#include "epicsExit.h" #include "epicsReadline.h" #define EPICS_COMMANDLINE_LIBRARY_EPICS 0 @@ -84,6 +85,14 @@ struct readlineContext { char *line; }; +static enum {rlNone, rlIdle, rlBusy} rlState = rlNone; + +static void rlExit(void *dummy) { + if (rlState == rlBusy) + rl_cleanup_after_signal(); +} + + /* * Create a command-line context */ @@ -92,6 +101,11 @@ epicsReadlineBegin(FILE *in) { struct readlineContext *readlineContext; + if (rlState == rlNone) { + epicsAtExit(rlExit, NULL); + rlState = rlIdle; + } + readlineContext = malloc(sizeof *readlineContext); if (readlineContext != NULL) { readlineContext->in = in; @@ -124,7 +138,9 @@ epicsReadline (const char *prompt, void *context) free (readlineContext->line); readlineContext->line = NULL; if (readlineContext->in == NULL) { + rlState = rlBusy; line = readline (prompt); + rlState = rlIdle; } else { line = (char *)malloc (linesize * sizeof *line);