运行简单的shell程序时出现分段错误

时间:2012-06-25 09:15:28

标签: c segmentation-fault

我正在尝试使用C语言创建一个简单的shell程序,它具有重定向stdin和stdout以及制作管道的选项,但它给了我一个分段错误错误。也许问题出在getline但我不确定。这是代码:

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

#define R 0
#define W 1
#define LINE_LEN 25

struct Job {
    char* command;
    char** argv;
    int stdin;
    int stdout;
} typedef Job;

int tokens_number = 0;
int sign_place = 0;
int contain_left = 0;
int contain_right = 0;
int contain_line = 0;

char** parse_cmdline (char * cmdline ){
    char** arg = calloc(15, sizeof(char*));
    char temp_cmd[LINE_LEN*10];
    strcpy(temp_cmd, cmdline);
    char * tmp;

    tmp = strtok(temp_cmd, " ");
    while(tmp != NULL) {
        arg[tokens_number] = (char*) malloc(LINE_LEN * sizeof(char*));
        strcpy(arg[tokens_number],tmp);
        tmp = strtok(NULL, " ");
        tokens_number++;
    }

    //LAST ELEMENT IS NULL
    arg[tokens_number+1] = NULL;
    return arg;
}

void check_for_special_signs(char** argv){
    int i;
    for(i=0; i<tokens_number; i++){
        if(strcmp(argv[i], "<") == 0){
            contain_left = 1;
            sign_place = i;
            return;
        }else if(strcmp(argv[i], ">") == 0){
            contain_right = 1;
            sign_place = i;
            return;
        }else if(strcmp(argv[i], "|") == 0){
            contain_line = 1;
            sign_place = i;
            return;
        }
    }
}

void fork_child(Job* my_job) {
    pid_t pid = fork();
    if (pid == 0) {
        execv(my_job -> command, my_job -> argv);
        perror(my_job -> command);
    } else if (pid > 0) {
        int status;
        wait(&status);
    } else
        perror("fork");
}

char** create_argv(char** argv){
    int i;
    int j = 0;
    char** argvs = calloc(sign_place,sizeof(char*));
    if(sign_place!=0){
        for(i=0; i < sign_place ; i++){
            argvs[i] = (char*) malloc(sizeof(char*));
            strcpy(argvs[i],argv[i]);
        }
        return argvs;
    }else{
        return argv;
    }   
}

void close_job(Job* my_job) {
    if (my_job -> stdin != STDIN_FILENO)
        close(my_job -> stdin);
    if (my_job -> stdout != STDOUT_FILENO)
        close(my_job -> stdout);
    free(my_job);
}

int main() {
    size_t s = 512;
    char* buffer = malloc(s * sizeof(char));
        char** sep_cmd = malloc(s * sizeof(char));

    while (getline(&buffer, &s, stdin) != EOF) {
        Job* my_job;
        int my_pipe[2];
        int in = 0;
        int out = 1;

                sep_cmd = parse_cmdline(buffer);

        my_job->command = sep_cmd[0];

        my_job->argv = sep_cmd;
        my_job->stdin = in;
        my_job->stdout = out;

        check_for_special_signs(my_job->argv);

        pid_t pid = fork();

        if (pid == 0) {
            if(contain_left == 1){
                in = open(my_job->argv[sign_place + 1], O_RDONLY);
                if(in < 0){
                    perror("open()");
                }

                my_job->argv = create_argv(my_job->argv);
                my_job->stdin = in;
            }else if(contain_right == 1){
                out = open(my_job->argv[sign_place + 1], O_WRONLY | O_CREAT,
                        S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
                if (out < 0)
                    perror("open()");

                my_job->argv = create_argv(my_job->argv);
                my_job->stdout = out;
            }else if(contain_line == 1){
                pipe(my_pipe);
                if (my_job -> stdin == my_pipe[R])
                    close(my_pipe[W]);
                else
                    close(my_pipe[R]);
            }
            execv(my_job -> command, my_job -> argv);
            perror(my_job -> command);
        } else if (pid > 0) {
            int status;
            wait(&status);
        } else{
            perror("fork");
        }
        close_job(my_job);
        free(buffer);
        buffer = (char*) malloc(s * sizeof(char));

    }
    free(buffer);
    return 0;
}

这样我就看不出代码中是否有更多错误。如果你看到更多的错误也请列出来。 谢谢。

1 个答案:

答案 0 :(得分:4)

您忘记在主要功能

中为my_job分配内存