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

Reply via email to