0

単純に ls -l | をパイプすると これでソートすると、プログラムは ls -l からの結果を無限に吐き出すだけです。誰が何が悪いのか見ることができますか?main 関数だけを見る必要があると仮定します。ただし、これはコンパイルされます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/wait.h>


#define COMMAND_LINE_LENGTH 256
#define HISTORY_LENGTH 10
#define TOKEN_MAX 50
#define DIRECTORY_LENGTH 5
#define DIRECTORY_PREFIX "/bin/"

struct prog_def
{
    //Binary location
    char *bin;

    //Is this program expecting a pipe?
    int expecting_pipe;

    //Arguments
    char *args[TOKEN_MAX + 1];

    pid_t pid;

} prog_def;

int get_prog_defs(const char* buf, struct prog_def prog_defs[])
{
    char *line = malloc(strlen(buf) + 1);

    int prog_count = 0;
    char* token;

    strcpy(line, buf);
    line[strlen(buf)] = 0;

    while(1)
    {
        int arg_count = 0;

        //The first time through we have to pass the line
        token = strtok(line, " ");

        //Each subsequent call we have to pass NULL
        //http://www.cplusplus.com/reference/cstring/strtok/
        line = NULL;

        //Start building the binary location string
        prog_defs[prog_count].bin = (char*)malloc(strlen(token) + DIRECTORY_LENGTH + 1);

        //Concatenate the directory prefix and command name
        strcat(prog_defs[prog_count].bin, DIRECTORY_PREFIX);
        strcat(prog_defs[prog_count].bin, token);

        //The first argument execvp will expect is the binary location itself
        //Redundant but if I wasn't too lazy to read the doc then I'd know why
        prog_defs[prog_count].args[arg_count++] = prog_defs[prog_count].bin;

        while(1)
        {
            prog_defs[prog_count].expecting_pipe = 0;

            //Check next token for end, pipe, IO redirection, or argument
            token = strtok(NULL, " ");

            //If we've consumed all tokens
            if (token == NULL)
                break;

            //Pipe
            if (strcmp(token, "|") == 0)
            {
                prog_defs[prog_count - 1].expecting_pipe = 1;
                break;
            }

            //Regular argument
            prog_defs[prog_count].args[arg_count++] = token;
        }

        ++prog_count;

        if (token == NULL) break;
    }

    return prog_count;
}


int main(int argc, char** argv)
{

    char command[COMMAND_LINE_LENGTH] = {0};

    //Generic loop counter
    int x = 0;

    while(1)
    {
        printf(">");

        //Get the command
        gets(command);

        struct prog_def prog_defs[TOKEN_MAX];
        int prog_count = get_prog_defs(command, prog_defs);

        //Keep the previous out fd for the in of the subsequent process
        int prev_out_fd = open("/dev/null", O_RDONLY);

        for (x = 0; x < prog_count; ++x)
        {
            //Create a pipe for both processes to share
            int pipefd[2];

            if (x != prog_count -1)
            {
                pipe(pipefd);
            }

            prog_defs[x].pid = fork();

            if(prog_defs[x].pid == 0)
            {
                dup2(prev_out_fd, STDIN_FILENO);
                close(pipefd[1]);

                if(x != prog_count - 1)
                {
                    dup2(pipefd[1], STDOUT_FILENO);
                    close(pipefd[0]);
                    close(pipefd[1]);
                }


                execvp(prog_defs[x].bin, prog_defs[x].args);
            prev_out_fd = pipefd[0];
            close(pipefd[1]);
            }

        close(prev_out_fd);

            prev_out_fd = pipefd[0];
            close(pipefd[1]);

        }

        printf("\n");

        for (x = 0; x < prog_count; ++x)
        {
            waitpid(prog_defs[x].pid, NULL, 0);
        }

    }
}
4

1 に答える 1

1

初期化されない文字列のメモリを取得するために呼び出すmallocため、ランダムなガベージが含まれます。次に、ランダムなガベージに別の文字列を追加しようとする which を呼び出しstrcat、ほぼ確実に malloc されたスペースの最後から実行され、ランダムな紛らわしい動作とクラッシュにつながります。

prog_defs[prog_count - 1]before ever every incrementingも使用するprog_countため、最初にループを通過するとき ( の場合prog_count == 0)、これは配列の開始前に書き込まれ、これもランダムな紛らわしい動作とクラッシュにつながります。

于 2013-02-09T00:43:30.413 に答える