简体   繁体   English

在C语言中为linux编写shell,exec用于某个特定进程是无限循环的

[英]Writing a shell in C for linux, exec for one certain process is infinitely looping

This is the relevant snippet of code: 这是相关的代码片段:

if(!strcmp(args[0],"run")){
                pid_t pid = fork();
                if(pid == 0){
                  execvp(args[1], args);
                  fprintf(stdout, "Process could not be found in this directory\n");
                  kill((int)getpid(), SIGKILL);
                }
                else{
                    if(pid < 0)
                        exit(1);

                    fprintf(stdout, "PID of Process = %d\n", pid);
                    int success = waitpid(pid, &childExitStatus, WUNTRACED | WCONTINUED);

                    if(success == -1)
                        exit(EXIT_FAILURE);
                }

            }

Now when I run a process like Libre Office math, it will only open one instance of it. 现在,当我运行像Libre Office数学这样的过程时,它只会打开它的一个实例。 However, when I try to open xterm using this code, it will continue to exec over and over, creating many instances of xterm before I do an interrupt and exit. 但是,当我尝试使用此代码打开xterm时,它将继续执行一遍又一遍,在我执行中断并退出之前创建了许多xterm实例。 I don't see any loops that would cause this to happen. 我没有看到任何会导致这种情况发生的循环。 Any insight into why this would be? 任何洞察为什么会这样?

The execvp() call is incorrect because it passes an additional argument "run" at the start. execvp()调用不正确,因为它在开始时传递了另一个参数“run”。 When executing xterm in this manner, the effect is similar to xterm xterm and has xterm use xterm as the shell. 以这种方式执行xterm时,效果类似于xterm xterm ,并且xterm使用xterm作为shell。 The new xterm inherits a SHELL environment variable that causes it to start another xterm, until limits are exhausted. 新的xterm继承了一个SHELL环境变量,导致它启动另一个xterm,直到限制耗尽。

In addition to jilles' answer to your immediate problem, you should know that calling fprintf if execvp fails is unwise as it can lead to duplication of previously-buffered output. 除了jilles对你当前问题的回答之外,你应该知道如果execvp失败则调用fprintf是不明智的,因为它可能导致重复先前缓冲的输出。 It also means you cannot safely use vfork , which can still be a valuable optimization (particularly if the parent process uses a lot of memory). 这也意味着你无法安全地使用vfork ,这仍然是一个有价值的优化(特别是如果父进程使用大量内存)。

There is no good way to report an exec failure, unfortunately. 遗憾的是,没有办法报告exec失败。 I tend to just do 我倾向于这样做

if (pid == 0) {
    execvp(...);
    /* if we got here, something bad happened */
    _exit(127);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM