Forking an interactive program from a curses process causes keyboard interference

74 Views Asked by At

From a curses interface, a user may fork a feh instance to view an image. The curses interface has hjkl navigation which should not be blocked as the image is viewed.

void display_file(void) {
    def_prog_mode();
    endwin();

    pid_t pid = fork();
    if (!pid) {
        execl("/usr/bin/feh", "feh", "/home/abc/main/violet.jpg", NULL);
    }

    reset_prog_mode();
    wrefresh(state_of_curses.a_win);
    wrefresh(state_of_curses.b_win);
}

This opens feh, and when feh is the active window, hjkl navigation affects feh only (as normal). But when the curses terminal is active, all keys seem to be sent randomly either to curses or to feh (ie hjkl may move the image, when it should only affect curses).

Why is this so? What is the right way to achieve the desired effect?

  • The program works as desired if I run feh in the background: execl("/bin/bash", "bash", "-c", "feh /home/abc/main/violet.jpg &", NULL);.
1

There are 1 best solutions below

0
user1121974 On

Fork gives the child the same open file descriptors as the parent's. Thus any characters sent to curses will also be sent to feh. Prevent writing to the child's STDIN to solve the problem.

void display_file(void) {
    def_prog_mode();
    endwin();

    pid_t pid = fork();
    if (!pid) {
        int fd = open("/dev/null", O_RDONLY);
        dup2(fd, STDIN_FILENO);
        close(fd);
        execl("/usr/bin/feh", "feh", "/home/abc/main/violet.jpg", NULL);
    }

    reset_prog_mode();
    wrefresh(state_of_curses.a_win);
    wrefresh(state_of_curses.b_win);
}