Невозможно правильно выйти из фона после использования fork в C. (Простая реализация оболочки) - PullRequest
0 голосов
/ 24 февраля 2020

Я реализую простую оболочку в C. RunCommand отлично работает для всех остальных процессов, но когда я запускаю программу, используя & (фоновый процесс). Подсказка командной строки застревает и больше не выдается, пока я снова не нажму клавишу ввода или другой ввод с клавиатуры.

Я не уверен, что именно вызывает эту проблему. Я реализовал грипп sh, чтобы очистить стандартный вывод, но ошибка все та же.

Основная функция драйвера. Запускается в al oop, чтобы продолжать запрашивать пользователя после каждого выполнения команды.

/* Simple Shell implementation. Prompts until exit received from user or any other errors */
int eggShell()
{
    char *lineRead;
    char **command;
    char *commandsPathFull = getenv("PATH"); //Get the $PATH in the environment

    while (1)
    {
        fflush(stdout);
        signal(SIGCHLD, sigchld_handler);

        lineRead = readline("esh> ");

        command = parseCommand(lineRead, " ");

        int backgroundTask = 0;

        if (command[0] != NULL)
        {
            if (strcmp(command[0], "exit") == 0)
            {
                free(command);
                free(lineRead);
                return 1;
            }

            if (command[1] != NULL)
            {
                for (size_t i = 1; command[i] != (char *)NULL; i++)
                {
                    if (strcmp(command[i], "&") == 0)
                    {
                        backgroundTask = 1;
                    }
                }
            }

            if ((validCommand(command[0], commandsPathFull)) == 1)
            {
                printf("Running Command\n");
                runCommand(command, backgroundTask);
                free(command);
                free(lineRead);
            }
        }

        fflush(stdout);
    }

    free(lineRead);
    free(command);
    return 1;
}

Команда Run запускает новый процесс для каждой команды. Если команда не является фоновой, команда parent не ожидает завершения дочернего процесса sh.

/* Receives a command and runs it using fork 
   returns 1 on successfull execution.*/
int runCommand(char **command, int bckTask)
{
    pid_t pid, wpid;
    int status;

    pid = fork();

    // Child process
    if (pid == 0)
    {
        //Execute the command
        if (execvp(command[0], command) == -1)
        {
            perror("esh Exec:");
        }
        exit(EXIT_FAILURE);
    }
    // Error forking
    else if (pid < 0)
    {
        perror("esh fork error:");
    }
    // Parent process
    else
    {

        // wait until either the processes are exited or killed
        // If not a background task
        if (bckTask != 1)
        {
            // {
            do
            {
                wpid = waitpid(pid, &status, WUNTRACED);
                if (wpid == -1)
                {
                    perror("Esh Wait PID:");
                }
            } while (!WIFEXITED(status) && !WIFSIGNALED(status));
            //printf("Foreground Task\n");
            //waitpid(pid, &status, 0);
        }
        else if (bckTask == 1)
        {
            printf("Command %s | Background PID: %d\n", command[0], pid);

            return 1;
            // do
            // {
            //  wpid = waitpid(-1, &status, WNOHANG);
            //  printf("Background pid: %d\n", pid);

            //  if (wpid > 0)
            //  {
            //      printf("Completed Background pid: %d\n", wpid);
            //  }
            // } while (!WIFEXITED(status) && !WIFSIGNALED(status));
        }
    }

    return 1;
}

Текущий вывод:

esh> ls
Running Command
esh  esh.c  Makefile  README.md
esh> echo "Hello World"
Running Command
"Hello World"
esh> echo "Hello 2" &
Running Command
Command echo | Background PID: 16618
esh> "Hello 2" &
(At this point the cursor is stuck. I need to press enter again to get the prompt)
esh> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...