Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ctrl-z (SIGSTOP) is not handled properly. #141

Open
krux02 opened this issue May 18, 2017 · 8 comments
Open

Ctrl-z (SIGSTOP) is not handled properly. #141

krux02 opened this issue May 18, 2017 · 8 comments

Comments

@krux02
Copy link

krux02 commented May 18, 2017

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
@mgood7123
Copy link

how do u make ur prompt look like that 0.0

@krux02
Copy link
Author

krux02 commented Oct 20, 2018

it is fish

@Sonophoto
Copy link

@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?

@krux02
Copy link
Author

krux02 commented Oct 22, 2018

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.

@Sonophoto
Copy link

@krux02

Well, I'm language agnostic professionally but personally I am a C snob too 😊 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!

@Sonophoto
Copy link

Sonophoto commented Oct 25, 2018

@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.

@Sonophoto
Copy link

@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.

raku-community-modules/Linenoise@7d0bb83

@afmayer
Copy link

afmayer commented Oct 26, 2018

There is a very simple way to implement CTRL+Z functionality, as shown by Steve Bennett in his fork of linenoise: msteveb@29aedbd

I have adapted the patch so it applies on top of the current master (4a961c0) and this is the result:

commit d9400774549967cda04cfa04f56ed956cd79147c
Author: Steve Bennett <steveb@workware.net.au>
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 <steveb@workware.net.au>
    
    (adaptations)
    
    Signed-off-by: Alexander F. Mayer <tinybluebutton@gmail.com>

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);

@krux02 krux02 changed the title Ctrl-z Ctrl-z (SIGSTOP) is not handled properly. Oct 28, 2018
gsauthof added a commit to gsauthof/duckdb that referenced this issue Jan 8, 2024
In a terminal, Ctrl+Z yields SIGTSTP, which is delivered to the
foreground process. It's default action is Stop and a
shell that supports job control takes over and adds the stopped process
into its list of suspended jobs.

In contrast to SIGSTOP, SIGTSTP can be caught or ignored. A common use
case for catching it is to restore the terminal to a state in which the
shell is usable again followed by suspension.

Almost all command line and text user interface programs support SIGTSTP
and work well in combination with shell job control.

This change is inspired by a patch posted in:

antirez/linenoise#141 (comment)

The traditional approach to catching and raising SIGTSTP in a signal
handler is detailed in:

https://man7.org/tlpi/code/online/dist/pgsjc/handling_SIGTSTP.c.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants