C:将stdin和stderr重定向到同一文件的自定义外壳程序即使在发生错误后也继续侦听输入

问题描述

我正在为一个类编写自定义外壳程序,但是我不确定为什么我的外壳程序在execvp和无效命令后挂起(并根据需要将其重定向到指定的文件)。我发现可以避免这种情况的方法是在exit(1)语句之后(发生错误检查的地方)添加一个execvp语句。我的文件描述符有问题吗?还是罚款exit(1)

execvp的代码,并处理&>,1>,2>,>,

// runs non pipe/redirection commands
void runSimple(char **args)
{
    pid_t pid;
    pid = fork();
    int i = 0;
    int fd;

    if (pid < 0) // error
    {
        printf("An error occured while forking child for runSimple.\n");
        exit(-1);
    }
    else if (pid == 0) // child
    {
        // fflush(stdin);
        // fflush(stdout);
        // fflush(stderr);

        // loop and deal with special operators
        while (args[i])
        {
            printf("%s\n",args[i]);
            // deal with &>
            if (!strcmp(args[i],"&>"))
            {
                fd = creat(args[i + 1],0644);
                if (fd < 0)
                {
                    perror("open");
                    exit(1);
                }

                dup2(fd,STDOUT_FILENO);
                dup2(STDOUT_FILENO,STDERR_FILENO);
                close(fd);
                args[i] = NULL;
            }

            // deal with 2>
            if (args[i] && !strcmp(args[i],"2>"))
            {

                fd = creat(args[i + 1],0644);
                if (fd < 0)
                {
                    perror("open");
                    exit(1);
                }
                dup2(fd,STDERR_FILENO);
                close(fd);
                args[i] = NULL;
            }

            // deal with > and 1>
            if (args[i] && (!strcmp(args[i],">") || !strcmp(args[i],"1>")))
            {
                fd = creat(args[i + 1],0644);
                if (fd < 0)
                {
                    perror("runSimple: error opening argument for >");
                    exit(1);
                }
                dup2(fd,STDOUT_FILENO); // make child's stdout into file
                close(fd);
                args[i] = NULL;
            }

            // deal with <,making sure to check if args[i] exists first
            if (args[i] && !strcmp(args[i],"<"))
            {
                fd = open(args[i + 1],O_RDONLY);
                if (fd < 0)
                {
                    perror("runSimple: error opening argument for <");
                    exit(1);
                }
                dup2(fd,STDIN_FILENO);
                close(fd);
                args[i] = NULL;
            }

            i++;
        }

        // exec input with appropriate fd
        execvp(args[0],args);
        perror("execvp");
        exit(1);
    }

    int status;
    waitpid(pid,&status,0);
}

runSimple一个函数,其中args是要运行的每个令牌命令的字符串列表的单个输入。例如,args可能是["ls",'-al","&>","outputFile"](当前有效,因为没有错误。程序在发生错误时冻结,例如args为:["asdfsdf","outputFile"]

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)