更改不相关的代码会产生分段错误。它为什么这样做?

时间:2017-03-02 02:22:42

标签: c shell segmentation-fault

我正在创建自己的Shell,并且通过使用我的is_background函数找到了&,我成功地让进程在后台运行。它工作正常,直到我试图实现标准输出的重定向。 chk_if_output函数是其中的一部分以及if语句if(out [0] == 1)在process函数中。以某种方式实现重定向搞砸了我实现后台进程的方式。如果我注释掉重定向代码,它会再次起作用。每当我尝试使用程序中的重定向代码运行后台进程时,我就会出现分段错误,而且我不能为我的生活找出原因。我没有更改任何后台进程代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX_LINE 80 /* The maximum length command */

int is_background(char *args[], int size){
    int background = 0;
    if (strcmp(args[size-1 ], "&") == 0){
        background = 1;
        args[size-1] = NULL;
    }
    return background;
}

int * chk_if_output(char *args[], int size){
    int * out = malloc(2);
    out[0] = 0; out[1] = 0;
    for (int i = 0; i < size; i++){
        if (strcmp(args[i],">") == 0){
            out[0] = 1;
            out[1] = i;
            break;
        }
    }   
    return out;
}
void process(char *command, char *params[], int size){
    pid_t pid;
    int background = is_background(params, size);
    int *out = chk_if_output(params, size);
    int fd;
    int fd2;
    pid = fork();
    if (pid < 0) {
        fprintf(stderr, "Fork Failed\n");
    }else if (pid == 0) {
        if(out[0] == 1){
            for (int i = out[1]; i < size; i++){
                params[i] = params[i+1];
            }
            fd = open(params[out[1]-1],O_RDONLY,0);
            dup2(fd,STDIN_FILENO);
            close(fd);
            fd2 = creat(params[out[1]],0644);
            dup2(fd2,STDOUT_FILENO);
            close(fd2);
            out[0] = 0;
            out[1] = 0;     
        }
        execvp(command, params);
    }else {
        if(background == 1){
            waitpid(pid, NULL, 0);
        }
        background = 0;
    }
}
int main(void) { 
    char *args[MAX_LINE/2 + 1]; /* command line arguments */ 
    int should_run = 1; /* flag to determine when to exit program */
    while (should_run) {
        char *line;
        char *endline; 
        printf("Leyden_osh>");

        fgets(line, MAX_LINE*sizeof line, stdin);

        if((endline = strchr(line, '\n')) != NULL){
            *endline = '\0';
        }

        if (strcmp((const char *)line,"exit") == 0){
            should_run = 0;
        }

        int i = 0;
        args[i] = strtok(line, " ");
        do{
            args[++i] = strtok(NULL, " ");
        }while(args[i] != NULL);

        process(args[0], args, i);

        fflush(stdout);

        return 0;
    }

1 个答案:

答案 0 :(得分:0)

在chk_if_output()函数中,循环中数组的最后一个元素是NULL。

通过循环到大小-1来修复它。