форк, exec и чтение из оболочки не удается - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть следующий фрагмент кода, который выполняет fork() с последующим execlp() для выполнения дочернего процесса.

/*
 * Spawns a child process. Behaviour can be controlled using flag.
 * Limited to 2 arguments to a program, flag works on bit set.
 */
static void
spawn(const char *file, const char *arg1, const char *arg2, const char *dir, uchar flag)
{
    static char *shlvl;
    static pid_t pid;
    static int status;

    if (flag & F_NORMAL)
        exitcurses();

    pid = fork();
    if (pid == 0) {
        if (dir != NULL)
            status = chdir(dir);

        shlvl = getenv("SHLVL");

        /* Show a marker (to indicate nnn spawned shell) */
        if (flag & F_MARKER && shlvl != NULL) {
            printf("\n +-++-++-+\n | n n n |\n +-++-++-+\n\n");
            printf("Next shell level: %d\n", atoi(shlvl) + 1);
        }

        /* Suppress stdout and stderr */
        if (flag & F_NOTRACE) {
            int fd = open("/dev/null", O_WRONLY, 0200);

            dup2(fd, 1);
            dup2(fd, 2);
            close(fd);
        }

        if (flag & F_NOWAIT) {
            signal(SIGHUP, SIG_IGN);
            signal(SIGPIPE, SIG_IGN);
            setsid();
        }

        if (flag & F_SIGINT)
            signal(SIGINT, SIG_DFL);
        execlp(file, file, arg1, arg2, NULL);
        _exit(1);
    } else {
        if (!(flag & F_NOWAIT))
            /* Ignore interruptions */
            while (waitpid(pid, &status, 0) == -1)
                DPRINTF_D(status);

        DPRINTF_D(pid);
        if (flag & F_NORMAL)
            refresh();
    }
}

Я пытаюсь выполнить следующий скрипт (имя файла: nscript):

#!/bin/sh

echo Press Enter to continue...
read arg

Я передаю флаги F_NORMAL | F_SIGINT на spawn().

Однако, похоже, что в сценарии ввод никогда не достигает read, и мне приходится убивать программу:

$ ./nnn
Press Enter to continue...


^C^\fish: “./nnn” terminated by signal SIGQUIT (Quit request from job control with core dump (^\))

Соответствующий код можно найти здесь: https://github.com/jarun/nnn/blob/v1.9/nnn.c#L692-L748

Воспроизвести,

  1. Установить nnn
  2. Run

    export NNN_SCRIPT=/usr/local/bin/nscript
    nnn
    
  3. Нажмите R

Заранее большое спасибо!

...