Changeset: b36aaec08ac6 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b36aaec08ac6 Modified Files: clients/mapiclient/ReadlineTools.c clients/mapiclient/ReadlineTools.h clients/mapiclient/mclient.c common/stream/stdio_stream.c Branch: client_interrupts Log Message:
Make readline and non-readline interrupts more alike. diffs (215 lines): diff --git a/clients/mapiclient/ReadlineTools.c b/clients/mapiclient/ReadlineTools.c --- a/clients/mapiclient/ReadlineTools.c +++ b/clients/mapiclient/ReadlineTools.c @@ -425,23 +425,27 @@ bailout: } static sigjmp_buf readline_jumpbuf; +static volatile sig_atomic_t mayjump; void -readline_int_handler(bool dojump) +readline_int_handler(void) { - if (dojump) + if (mayjump) { + mayjump = false; siglongjmp(readline_jumpbuf, 1); - rl_on_new_line(); // Regenerate the prompt on a newline - rl_replace_line("", 0); // Clear the previous text - rl_redisplay(); + } } char * call_readline(const char *prompt) { + char *res; if (sigsetjmp(readline_jumpbuf, 0) != 0) - return strdup("\200"); /* interrupted */ - return readline(prompt); /* normal code path */ + return (char *) -1; /* interrupted */ + mayjump = true; + res = readline(prompt); /* normal code path */ + mayjump = false; + return res; } void diff --git a/clients/mapiclient/ReadlineTools.h b/clients/mapiclient/ReadlineTools.h --- a/clients/mapiclient/ReadlineTools.h +++ b/clients/mapiclient/ReadlineTools.h @@ -22,7 +22,7 @@ void deinit_readline(void); void save_line(const char *s); rl_completion_func_t *suspend_completion(void); void continue_completion(rl_completion_func_t * func); -void readline_int_handler(bool dojump); +void readline_int_handler(void); char *call_readline(const char *prompt); #endif /* HAVE_LIBREADLINE */ diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c --- a/clients/mapiclient/mclient.c +++ b/clients/mapiclient/mclient.c @@ -1402,11 +1402,16 @@ SQLpagemove(int *len, int fields, int *p mnstr_printf(toConsole, "next page? (continue,quit,next)"); mnstr_flush(toConsole, MNSTR_FLUSH_DATA); sz = mnstr_readline(fromConsole, buf, sizeof(buf)); - if (sz > 0) { + if (sz < 0 && mnstr_errnr(fromConsole) == MNSTR_INTERRUPT) { + /* interrupted, equivalent to typing 'q' */ + mnstr_clearerr(fromConsole); + *skiprest = true; + } else if (sz > 0) { if (buf[0] == 'c') *ps = 0; if (buf[0] == 'q') *skiprest = true; + /* make sure we read the whole line */ while (sz > 0 && buf[sz - 1] != '\n') sz = mnstr_readline(fromConsole, buf, sizeof(buf)); } @@ -1416,8 +1421,7 @@ SQLpagemove(int *len, int fields, int *p static volatile sig_atomic_t state; #define READING 1 -#define READMORE 2 -#define WRITING 3 +#define WRITING 2 #define IDLING 0 static void @@ -1425,17 +1429,10 @@ sigint_handler(int signum) { (void) signum; - mnstr_write(toConsole, "\n", 1, 1); + state = IDLING; #ifdef HAVE_LIBREADLINE - if (state == READING) { - readline_int_handler(false); - } else if (state == READMORE) { - /* set state before the call since it jumps away */ - state = IDLING; - readline_int_handler(true); - } + readline_int_handler(); #endif - state = IDLING; } static void @@ -2123,26 +2120,29 @@ doFileBulk(Mapi mid, stream *fp) length = 0; buf[0] = 0; } else { - if ((length = mnstr_read(fp, buf, 1, bufsize)) < 0) { + while ((length = mnstr_read(fp, buf, 1, bufsize)) < 0) { + if (mnstr_errnr(fp) == MNSTR_INTERRUPT) + continue; /* error */ errseen = true; - break; /* nothing more to do */ + break; + } + if (errseen) + break; /* nothing more to do */ + buf[length] = 0; + if (length == 0) { + /* end of file */ + if (semicolon2 == 0 && hdl == NULL) + break; /* nothing more to do */ } else { - buf[length] = 0; - if (length == 0) { - /* end of file */ - if (semicolon2 == 0 && hdl == NULL) - break; /* nothing more to do */ - } else { - if (strlen(buf) < (size_t) length) { - mnstr_printf(stderr_stream, "NULL byte in input\n"); - errseen = true; - break; - } - while (length > 1 && buf[length - 1] == ';') { - semicolon1++; - buf[--length] = 0; - } + if (strlen(buf) < (size_t) length) { + mnstr_printf(stderr_stream, "NULL byte in input\n"); + errseen = true; + break; + } + while (length > 1 && buf[length - 1] == ';') { + semicolon1++; + buf[--length] = 0; } } } @@ -2273,14 +2273,14 @@ myread(void *restrict private, void *res if (strcmp(p->prompt, "more>") == 0) { func = suspend_completion(); - state = READMORE; - } else { - state = READING; } p->buf = call_readline(p->prompt); - state = IDLING; if (func) continue_completion(func); + if (p->buf == (char *) -1) { + p->buf = NULL; + return -1; + } if (p->buf == NULL) return 0; p->len = strlen(p->buf); @@ -2373,9 +2373,7 @@ doFile(Mapi mid, stream *fp, bool useins } do { -#ifndef HAVE_LIBREADLINE repeat: -#endif bool seen_null_byte = false; if (prompt) { @@ -2395,14 +2393,12 @@ doFile(Mapi mid, stream *fp, bool useins for (;;) { ssize_t l; char *newbuf; -#ifndef HAVE_LIBREADLINE state = READING; -#endif l = mnstr_readline(fp, buf + length, bufsiz - length); -#ifndef HAVE_LIBREADLINE if (l == -1 && state == IDLING) { /* we were interrupted */ mnstr_clearerr(fp); + mnstr_write(toConsole, "\n", 1, 1); if (hdl) { /* on interrupt when continuing a query, force an error */ buf[0] = '\200'; @@ -2415,7 +2411,6 @@ doFile(Mapi mid, stream *fp, bool useins } } state = IDLING; -#endif if (l <= 0) break; if (!seen_null_byte && strlen(buf + length) < (size_t) l) { diff --git a/common/stream/stdio_stream.c b/common/stream/stdio_stream.c --- a/common/stream/stdio_stream.c +++ b/common/stream/stdio_stream.c @@ -36,8 +36,9 @@ file_read(stream *restrict s, void *rest } if (elmsize && cnt) { + errno = 0; if ((rc = fread(buf, elmsize, cnt, fp)) == 0 && ferror(fp)) { - mnstr_set_error_errno(s, MNSTR_READ_ERROR, "read error"); + mnstr_set_error_errno(s, errno == EINTR ? MNSTR_INTERRUPT : MNSTR_READ_ERROR, "read error"); return -1; } s->eof |= rc == 0 && feof(fp); _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org