Как правильно использовать fork, exec, wait
Оболочка, которую я пишу, должна выполнить программу, предоставленную ей пользователем. Здесь очень сокращенная упрощенная версия моей программы
int main()
{
pid_t pid = getpid(); // this is the parents pid
char *user_input = NULL;
size_t line_sz = 0;
ssize_t line_ct = 0;
line_ct = getline(&user_input, &line_sz, stdin); //so get user input, store in user_input
for (;;)
{
pid_t child_pid = fork(); //fork a duplicate process
pid_t child_ppid = getppid(); //get the child parent pid
if (child_ppid == pid) //if the current process is a child of the main process
{
exec(); //here I need to execute whatever program was given to user_input
exit(1); //making sure to avoid fork bomb
}
wait(); //so if it the parent process we need to wait for the child process to finish, right?
}
}
- Развернул ли я новый процесс и проверил, правильно ли он работает с дочерним процессом.
- Какой exec я могу использовать здесь для того, что я пытаюсь сделать? Самый простой способ
- Каковы мои аргументы, чтобы ждать? документация, на которую я смотрю, не помогает.
Предположим, что пользователь может ввести что-то вроде ls, ps, pwd
Спасибо.
Edit:
const char* hold = strdup(input_line);
char* argv[2];
argv[0] = input_line;
argv[1] = NULL;
char* envp[1];
envp[0] = NULL;
execve(hold, argv, envp);
Ответы
Ответ 1
Здесь простое, читаемое решение:
pid_t parent = getpid();
pid_t pid = fork();
if (pid == -1)
{
// error, failed to fork()
}
else if (pid > 0)
{
int status;
waitpid(pid, &status, 0);
}
else
{
// we are the child
execve(...);
_exit(EXIT_FAILURE); // exec never returns
}
Ребенок может использовать сохраненное значение parent
, если ему нужно знать родительский PID (хотя я не в этом примере). Родитель просто ждет, пока ребенок закончит. Фактически, ребенок запускается "синхронно" внутри родителя, и нет parallelism. Родитель может запросить status
, чтобы узнать, каким образом ребенок вышел (успешно, безуспешно или с сигналом).