Linenoise: Ctrl-z (SIGSTOP) is not handled properly.

Created on 18 May 2017  ·  8Comments  ·  Source: antirez/linenoise

When I press ctrl-z on the terminal (sending SIGSTOP) it just puts an on the input line. I don't know why and how, but the program is supposed to stop and return to the shell. Then with the command fg I should be able to go back to the process.

┬─[arne@arne-thinkpad:~/proj/c++/linenoise]─[18:05:53]
╰─>$ ./linenoise_example 
hello> foo
echo: 'foo'
hello> 
echo: ''
hello> 

┬─[arne@arne-thinkpad:~/proj/c++/linenoise]─[18:05:54]
╰─>$ python
Python 3.6.1 (default, Mar 27 2017, 00:27:06) 
[GCC 6.3.1 20170306] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> foo = 17
'python' has gestoppt

┬─[arne@arne-thinkpad:~/proj/c++/linenoise]─[18:06:07]
│ 1 28968   0%  gestoppt    python
╰─>$ fg
Job 1, 'python' in den Vordergrund schicken

>>> print(foo)
17

Most helpful comment

There is a very simple way to implement CTRL+Z functionality, as shown by Steve Bennett in his fork of linenoise: https://github.com/msteveb/linenoise/commit/29aedbd22b5e3529aff1f85ec1b3164118b83291

I have adapted the patch so it applies on top of the current master (https://github.com/antirez/linenoise/commit/4a961c0108720741e2683868eb10495f015ee422) and this is the result:

commit d9400774549967cda04cfa04f56ed956cd79147c
Author: Steve Bennett <[email protected]>
Date:   Mon Jan 1 13:11:16 2018 +1000

    Enable ^Z (SUSP) support

    Allows the current process to be backgrounded and then resumed.

    Signed-off-by: Steve Bennett <[email protected]>

    (adaptations)

    Signed-off-by: Alexander F. Mayer <[email protected]>

diff --git a/linenoise.c b/linenoise.c
index 10ffd71..d861505 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -109,6 +109,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <sys/stat.h>
@@ -168,6 +169,7 @@ enum KEY_ACTION{
    CTRL_T = 20,        /* Ctrl-t */
    CTRL_U = 21,        /* Ctrl+u */
    CTRL_W = 23,        /* Ctrl+w */
+   CTRL_Z = 26,        /* Ctrl+z */
    ESC = 27,           /* Escape */
    BACKSPACE =  127    /* Backspace */
 };
@@ -830,6 +832,16 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
         case CTRL_C:     /* ctrl-c */
             errno = EAGAIN;
             return -1;
+        case CTRL_Z:     /* ctrl-z */
+#ifdef SIGTSTP
+            /* send ourselves SIGSUSP */
+            disableRawMode(STDIN_FILENO);
+            raise(SIGTSTP);
+            /* and resume */
+            enableRawMode(STDIN_FILENO);
+            refreshLine(&l);
+#endif
+            continue;
         case BACKSPACE:   /* backspace */
         case 8:     /* ctrl-h */
             linenoiseEditBackspace(&l);

All 8 comments

how do u make ur prompt look like that 0.0

it is fish

@krux02 I see you are using c++, @yhirose has a linenoise that has been ported to c++ :https://github.com/yhirose/cpp-linenoise. It is also UTF8 enabled.

Can you share a gist of your linenoise_example code?

Actually I am not using c++. I used to program a lot of C++ but now I do Nim. Just for the example I wanted to make sure that my problem does not come from anything Nim related, so I created a c++ project.

From my experience the C API is just fine, I don't need a c++ version. Also I had no problems at all to use utf8 in this library. What I am missung are many keyboard commands that I am already very familiar with on readline.

I use a wrapped version of linenoise, so I am not so sure if it really is worth a lot for you, but this is the example that I use and it is not linenoise oriented: https://github.com/krux02/opengl-sandbox/blob/master/examples/console.nim

The idea in that file it to use the macro system of Nim to make an arbitrary function available in the command interpreter. But under the hood the command interpreter is linenoise.

@krux02

Well, I'm language agnostic professionally but personally I am a C snob too :blush: I love C.

Remember, Linenoise is a bare bones, no frills library, that is a design goal.

I want to look into this unfortunately I won't have time until this weekend, leave this open unless someone solves it for you.

Hey! You are on the front page of Nim! Good Job Arne!

@krux02

Ok, this C project shows the behaviour that you are describing:

https://github.com/Sonophoto/shellnoise

Ctrl-C and Ctrl-D however behave normally.

Linenoise appears to be capturing the Ctrl-Z as input (and in this example it is simply echoed onto the terminal as a string) instead of passing it through to the shell.

Oh and note that this project is using linenoise multi-line input.

@krux02

My best guess with a little digging is that linenoise puts the terminal into a raw mode and that setup is causing it to capture the Ctrl-Z as a character instead of as an ASCII control code.

https://github.com/antirez/linenoise/blob/master/linenoise.c#L217-L251

and U+001A IS the Ctrl-Z code when printed in UTF8

@hoelzro came up with this patch but it doesn't handle the Ctrl-C correctly. However that could be captured as well and simply handled in linenoise.

https://github.com/hoelzro/p6-linenoise/commit/7d0bb83cab34ca58f7a487b5df30736d058112cf

There is a very simple way to implement CTRL+Z functionality, as shown by Steve Bennett in his fork of linenoise: https://github.com/msteveb/linenoise/commit/29aedbd22b5e3529aff1f85ec1b3164118b83291

I have adapted the patch so it applies on top of the current master (https://github.com/antirez/linenoise/commit/4a961c0108720741e2683868eb10495f015ee422) and this is the result:

commit d9400774549967cda04cfa04f56ed956cd79147c
Author: Steve Bennett <[email protected]>
Date:   Mon Jan 1 13:11:16 2018 +1000

    Enable ^Z (SUSP) support

    Allows the current process to be backgrounded and then resumed.

    Signed-off-by: Steve Bennett <[email protected]>

    (adaptations)

    Signed-off-by: Alexander F. Mayer <[email protected]>

diff --git a/linenoise.c b/linenoise.c
index 10ffd71..d861505 100644
--- a/linenoise.c
+++ b/linenoise.c
@@ -109,6 +109,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <sys/stat.h>
@@ -168,6 +169,7 @@ enum KEY_ACTION{
    CTRL_T = 20,        /* Ctrl-t */
    CTRL_U = 21,        /* Ctrl+u */
    CTRL_W = 23,        /* Ctrl+w */
+   CTRL_Z = 26,        /* Ctrl+z */
    ESC = 27,           /* Escape */
    BACKSPACE =  127    /* Backspace */
 };
@@ -830,6 +832,16 @@ static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen,
         case CTRL_C:     /* ctrl-c */
             errno = EAGAIN;
             return -1;
+        case CTRL_Z:     /* ctrl-z */
+#ifdef SIGTSTP
+            /* send ourselves SIGSUSP */
+            disableRawMode(STDIN_FILENO);
+            raise(SIGTSTP);
+            /* and resume */
+            enableRawMode(STDIN_FILENO);
+            refreshLine(&l);
+#endif
+            continue;
         case BACKSPACE:   /* backspace */
         case 8:     /* ctrl-h */
             linenoiseEditBackspace(&l);

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  ·  4Comments

fatcerberus picture fatcerberus  ·  5Comments

denisvm picture denisvm  ·  9Comments

JelteF picture JelteF  ·  8Comments

ozancaglayan picture ozancaglayan  ·  21Comments