【问题标题】:C microshell Segfaulting with one argument, but not with two [closed]C microshell Segfaulting 有一个参数,但不是两个[关闭]
【发布时间】:2017-04-04 23:58:57
【问题描述】:

我正在创建一个微型外壳,它将接收输入并为我提供 unix 系统输出。我正在使用 ||而不仅仅是|为管道。如果我给它两个由 || 分隔的参数,我的 shell 运行良好,但如果我只给它一个参数,它会出现段错误。谁能帮我这个?我已经调试了几个小时没有运气。提前谢谢!

 #include <iomanip>
 #include <iostream>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <errno.h>
 #include <stdio.h>

 using namespace std;
int main()
{
    char command[160];
    pid_t pid1 = 1, pid2 = 1;

    cout << "myshell> ";
    cin.getline(command, 160);

    while (strcmp(command, "q") != 0 && strcmp(command, "quit") != 0 && pid1 > 0
            && pid2 > 0)
    {
        char* arg1[6];
        char* arg2[6];
        char path1[21], path2[21];
        int pipefd[2];
        arg1[0] = NULL;
        arg2[0] = NULL;

        getParms(command, arg1, arg2);

        if (pipe(pipefd) < 0)
        {
            perror("Pipe");
            exit(-1);
        }

        pid1 = fork();
        if (pid1 < 0)
        {
            perror("Fork");
            exit(-1);
        }

        if (pid1 == 0)
        {

            if (arg2[0] != NULL)
            {
                close(pipefd[0]);
                close(1);
                dup(pipefd[1]);
                close(pipefd[1]);
            }

            strcpy(path1, "/bin/");
            strcat(path1, arg1[0]);
            if (execvp(path1, arg1) < 0)
            {
                strcpy(path1, "/usr/bin/");
                strncat(path1, arg1[0], strlen(arg1[0]));
                if (execvp(path1, arg1) < 0)
                {
                    cout << "Couldn't execute " << arg1[0] << endl;
                    exit(127);
                }
            }

            if (arg2[0] == NULL)
            { // Parent process
                close(pipefd[0]); //read
                close(pipefd[1]); //write

                waitpid(pid1, NULL, 0); // Waits for child2
                cout << "myshell> ";
                cin.getline(command, 160);
            }
        }

        else if (arg2[0] != NULL)
        {
            pid2 = fork();
            if (pid2 < 0)
            {
                perror("Fork");
                exit(-1);
            }

            if (pid2 == 0)
            {
                close(pipefd[1]);
                close(0);

                dup(pipefd[0]);
                close(pipefd[0]);

                strcpy(path2, "/bin/");
                strncat(path2, arg2[0], strlen(arg2[0]));
                if (execvp(path2, arg2) < 0)
                {
                    strcpy(path2, "/usr/bin/");
                    strncat(path2, arg2[0], strlen(arg2[0]));
                    if (execvp(path2, arg2) < 0)
                    {
                        cout << "Couldn't execute " << arg2[0] << endl;
                        exit(127);
                    }
                }
            }

            else
            { // Parent process
                close(pipefd[0]); //read
                close(pipefd[1]); //write

                waitpid(pid2, NULL, 0); // Waits for child2
                cout << "myshell> ";
                cin.getline(command, 160);
            }
        }
    }
    return 0;
}

void getParms(char str[], char* args[], char* args2[])
{
    char* index;
    int i = 0;
    int j = 0;

    index = strtok(str, " ");

    // While the token isn't NULL or pipe
    while (index != NULL && strstr(index, "||") == NULL)
    {
        args[i] = index;
        index = strtok(NULL, " ");
        i++;
    }
    args[i] = (char*) NULL; // makes last element Null

    if (strstr(index, "||") != NULL)
    {
        index = strtok(NULL, " ");
        while (index != NULL)
        {
            args2[j] = index;
            index = strtok(NULL, " ");
            j++;
        }
    }

    args2[j] = (char*) NULL; // makes last element Null
}

【问题讨论】:

    标签: c++ unix pipe


    【解决方案1】:

    我猜了一下,因为您没有包含输入有效和无效输入的示例。

    如果您在调试器中查看此内容,您会发现如果您只提供一个参数(不带“||”),则在第二个循环之前调用 strstr 时,index 将为 NULL。由于 strstr 不期望 NULL 参数,因此导致崩溃。

    【讨论】:

    • 谢谢!工作参数的示例类似于 cat info.txt || sort ,但使用任何命令,但这会破坏它
    • 有没有办法检查“||”会接受 NULL 吗?
    • @GrapeSoda3 你想多了。 if (index != NULL &amp;&amp; strstr(index, "||") != NULL).
    • 如果我使用该代码运行任何东西,我会收到 fork 错误或输入输出错误
    猜你喜欢
    • 2018-06-06
    • 1970-01-01
    • 2013-08-25
    • 2011-04-21
    • 2023-03-23
    • 2023-04-08
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多