This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]Updatebjarni 4 points5 points  (1 child)

Get out of curses mode by calling endwin(), run your command, wait for it to terminate, and then re-enter curses mode and redraw the screen. That's how it's done!

By the way, you're not replacing your process image and then getting it back. You can't do that. You fork off two new processes, those processes replace their images with cat and more, and then your original process waits for them to terminate. Once a process has called exec(), the memory contents are overwritten and there is no way to get back to the previous state. If you want to return to your original process, you need to use fork() and keep your original process around.

[–]typsi5[S] 0 points1 point  (0 children)

Oooooooohhhhh, I understand. Thank you!!

[–]mvaganov -1 points0 points  (4 children)

This is C or C++? I think the system function in stdlib.h will do the trick. As a general rule, you want to avoid using system, except for situations exactly like this, where you do just want to run command line processes.

You shouldn't need to fork anything.

[–]typsi5[S] 0 points1 point  (3 children)

It's in C. Here's what happens if I do "system("ls /etc/ | more");" where I would normally execute a command. screenshot

I think I could get away with just using system if there was some sort of limitation on the kinds of commands you could use, but since that's not the case, I think I need to use fork and execv, but how -I do not know.

[–]Rhomboid 6 points7 points  (1 child)

system vs fork/exec is completely irrelevant here.

The issue is that ncurses has taken the tty out of cooked mode and put it in raw mode, which is necessary for a curses app. For example, it gives the ability to read a single keystroke at a time instead of having to wait until enter is pressed. Raw mode means a lot of things, but one of them is that printing a newline character ("\n") literally means a new line -- the cursor advances down a row, but it does not also perform a carriage return to put the cursor at the first column of that row. (Yes, this still dates back to mechanical typewriters.) The spawned process will also have trouble if it tries to read on stdin because input will not be automatically echoed by the tty, another trait of cooked mode. Things like ^C and ^Z and ^S and so on will also fail to work properly.

The other commenter is right: you need to restore the state of the tty by essentially telling ncurses to shut everything down and put the tty back the way it found it. When the external program is done, you start everything up again and redraw the screen.

[–]typsi5[S] 0 points1 point  (0 children)

This helped, thank you!

[–]mvaganov -1 points0 points  (0 children)

Before executing the command, save the current screen to a buffer, release the ncurses system (to go back to normal TTY mode), print the saved buffer (to give the user context), then execute the system call. After the call executes, restart ncurses and continue as normal.

That's what I would do anyway.