使用 fork() 和 execvp() 函数创建 C 程序时遇到问题

Posted

技术标签:

【中文标题】使用 fork() 和 execvp() 函数创建 C 程序时遇到问题【英文标题】:Trouble creating a C program using fork() and execvp() functions 【发布时间】:2016-03-03 20:44:31 【问题描述】:

这是我目前遇到问题的以下代码:

#include <stdio.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

#define MAX_LINE 80

int main(void)

    char *args[MAX_LINE/2+1];
    int background= 0;//integer that acts a boolean for if & appears
    int should_run = 1;
    int status;

        while(should_run)//Just to keep the interface going until the user chooses to stop
        
            printf("osh>");//prompt
            fflush(stdout);

            int i = 0;
            while(getchar() != '\n')//Use scanf until a new line is found
            
                scanf("%s", &args[i]);

                if(strcmp(&args[i], "exit") == 0)//temporary exit protocal
                
                    printf("Exiting now...");
                    return 0;
                


                if(strcmp(&args[i], "&") == 0)//If we find a & in our input then we changed background to 1 or true
                    background = 1;
                printf("Args[%i] = %s\n", i, &args[i]);//Tester
                i++;
            


            printf("Background = %i\n",background);//Test
            pid_t pid= fork();// Create new child process
            printf("process %i created\n", pid);//Test



            if(pid < 0)//fork() failed
            
                printf("Fork Failed.\n");
                return 1;
            

            else if(pid == 0)//Child process id
            
                printf("Child process started %s command\n", &args[0]);
                if(execvp(args[0], args) < 0)//change the current child process to execute the input given by the user 
                                //with args[0] being the command and args being the parameters(ls -l is an example).
                
                    printf("Command failed\n");
                
                return 0;
            

            else//Parent Process
            
                if(background == 1)//If the user typed in a & then the parent will wait for a change in state from the child, if there is no &
                            //then we will just finish the parent process
                
                    printf("Parent process waiting on child\n");
                    wait(NULL);
                
            

        

    return 0;

我现在有一个大问题和一个小问题。主要问题是在 execvp 启动之前我有一个 printf 方法,上面写着“子进程已启动”,并且我打印了这一行,但是没有其他任何事情发生。没有引发中断,程序似乎只是在我的 execvp 命令上被冻结。

我的小问题是,当我的程序在要求输入之前启动提示“osh>”时。现在,例如,如果我输入“osh>ls -l”,那么我会得到 args[0] = s, args1 = -l。现在,如果我将“osh> ls -l”以这种确切的格式输入,我会得到 args[0] = ls, args1 = -l。这是我在这里没有正确使用的 scanf() 的一部分,以确保我在“osh>”之后和空格之间作为字符串得到任何字符?

编辑: 这是我的用户输入“ls -l”的输出

【问题讨论】:

您永远不会为args 中的指针分配内存。对它们的任何使用都有未定义的行为。 另外,如果你不做任何事情来确保最后一个参数之后的指针是NULLexecvp() 期望以这种方式标记参数列表的结尾。 【参考方案1】:

您遇到的缺少字符的问题是因为getchar()scanf 开始尝试之前消耗了您输入的第一个字符。您可能想要执行以下操作:

while (scanf("%s", &buffer) > 0)

    strcpy(args[i], buffer);
    /* then do stuff with args[i] */

【讨论】:

无论如何,这将是一个开始。人们还必须担心避免溢出缓冲区,并且由于还存在没有为参数分配空间的问题,在这种情况下,strdup() 可能是strcpy() 的有用替代方案。 当然。您还可以检查i 以确保您不会超出数组本身。

以上是关于使用 fork() 和 execvp() 函数创建 C 程序时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

pthread 的 malloc 内存,然后 fork + execvp

linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)

pthread并在C中递归调用execvp

fork与 execve的区别

C语言中 使用execl函数创建一个文件

Unix/Linux编程实践教程