关于linux:在c中为shell创建后台进程

Creating a background process for shell in c

我试图用C制作自己的shell,但是我在处理后台和前台进程时遇到了麻烦。这是我创建流程的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void call_exec(char *cmd)
{
pid_t cpid;
is_Background();
if(index(cmd, '/') == NULL) {
    int i;
printf("cmd is %s\
"
, cmd);
cpid = fork();
if(cpid == 0) {
    i = execvp(cmd, my_argv);
    if(i < 0) {
        printf("%s: %s\
"
, cmd,"command not found");
        exit(1);        
    }  
}
else {
    if(!is_BG ) {
        wait(NULL);
    }
    is_BG = 0;
}
}

is_Background:

1
2
3
4
5
6
void is_Background() {
if(strcmp(my_argv[arg_index],"&") == 0) {
    is_BG = 1;
    my_argv[arg_index] = NULL;
}
}

当我运行代码并在命令行中输入" gedit "时,shell会一直等到我关闭gedit窗口,然后提示我输入新命令。当我输入" gedit


这里有两个问题:

首先,gedit和firefox是单实例程序。任何其他调用都将仅重用现有实例。您在bash中看到了相同的东西:

1
2
bash$ gedit &   # Starts gedit and returns immediately
bash$ gedit     # Opens a new tab in the existing window and returns immediately

您应该改为使用多个实例程序(例如xtermxeyes)进行测试。

其次,您的wait(NULL)调用等待任何进程关闭,而不必等待最后一个进程。在您的shell中,您可能会看到以下内容:

1
2
3
yourshell$ xterm &  # starts xterms and returns immediately.
# Now close the xterm before running the next command
yourshell$ xeyes    # starts xeyes, waits on xterm, returns immediately

您可以改为使用waitpid(cpid, NULL, 0)等待正确的过程。