I've looked around, but there doesn't seem to be anything on using fork+exec with ncurses. Here's my attempt at a simple program:
#include <ncurses.h>
#include <unistd.h>
#include <sys/wait.h>
extern char **environ;
int
main(void){
initscr(); cbreak(); noecho();
pid_t child;
mvprintw(0, 0, "press to continue"), refresh();
getch();
if (!(child = fork())) {
def_prog_mode(), endwin();
if (execve("/bin/ksh", (char*[]){"ksh", NULL}, environ) < 0) {
perror("execve failed");
}
}
else if (child > 0) {
wait(&child);
reset_prog_mode(), refresh();
mvprintw(0, 0, "Done!"), refresh();
getch();
endwin();
}
else {
endwin();
perror("fork failed");
}
return 0;
}
It works fine, except output by the execve
-ed process is all below the shell prompt that I get once the program is finished. Video to understand what I mean.
What is the proper way to fork+exec without mangled output?
Turns out if I move def_prog_mode(), refresh()
out of the child process and into the parent process, everything works fine. Makes sense: two process controlling the same curses
window doesn't seem like something that'd work.
Here's the fixed code:
#include <ncurses.h>
#include <unistd.h>
#include <sys/wait.h>
extern char **environ;
int
main(void){
initscr(); cbreak(); noecho();
pid_t child;
mvprintw(0, 0, "press to continue"), refresh();
getch();
def_prog_mode(), endwin();
if (!(child = fork())) {
if (execve("/bin/ksh", (char*[]){"ksh", NULL}, environ) < 0) {
perror("execve failed");
}
}
else if (child > 0) {
wait(&child);
reset_prog_mode(), erase();
mvprintw(0, 0, "Done!"), refresh();
getch();
endwin();
}
else {
endwin();
perror("fork failed");
}
return 0;
}