【问题标题】:how to correctly use fork, exec, wait如何正确使用fork、exec、wait
【发布时间】:2013-10-06 15:18:09
【问题描述】:

我正在编写的 shell 需要执行用户给它的程序。这是我的程序的非常简短的简化版本

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's 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's the parent process we need to wait for the child process to finish, right?

    }
}
  1. 我是否对新进程进行了 fork 并检查它是否是正确的子进程
  2. 我可以在这里使用什么 exec 来完成我想要做的事情?最简单的方法是什么
  3. 我有什么理由等待?我正在查看的文档没有多大帮助

假设用户可能会输入诸如 ls、ps、pwd 之类的内容

谢谢。

编辑:

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);

【问题讨论】:

  • 在 Stackoverflow 上有很多类似的问题。

标签: c shell exec


【解决方案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
}

如果孩子需要知道父母的 PID,则可以使用存储的值parent(尽管我在这个例子中不知道)。父母只是等待孩子完成。实际上,子进程在父进程内部“同步”运行,并且没有并行性。父母可以查询status 以查看孩子以何种方式退出(成功、不成功或有信号)。

【讨论】:

  • 好吧,来自 linux 手册页: int execve(const char *filename, char *const argv[], char *const envp[]);你能在我的程序的上下文中解释这些论点吗
  • @user2079802:手册页没有解释execve 的工作原理吗?你也可以使用各种other exec interfaces
  • @user2079802:不需要strdupexecve(argv[0], argv, envp) 应该可以。
  • 其实子进程可以调用getppid()获取父进程的ID。无需提前保存。 :-)
  • @AlanHaggaiAlavi:少了一个系统调用 :-)
猜你喜欢
  • 2012-01-12
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 2015-10-06
  • 2014-04-21
  • 2012-01-03
  • 1970-01-01
相关资源
最近更新 更多