编写shell程序时的分段错误C.

时间:2014-02-26 08:35:31

标签: c shell unix

我的代码工作正常,直到我添加额外的东西,比如识别和处理cd,>,<,>>和|。你可以检查我的代码,看看错误发生在哪里? 顺便说一下,分配的要求最多只有1个管道。而且我认为问题从for循环开始,因为我把printf放在它之后,检查它是否会打印args [k],它确实然后错误弹出并且程序停止了。

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

int main()
{
  const int MAX_ARGS = 10;
  char *token[MAX_ARGS + 1]; /*assume max number of token <=10*/
  char *temp;
  char line[256], command[MAX_ARGS];
  char prompt[] = "sh2 % ";
  pid_t pid;
  int i=0, j,k, status;

  printf("%s", prompt);

  while (fgets(line, sizeof line, stdin) != NULL)
  {
    line[strlen(line)-1] = '\0';    /*get rid of \n*/
    token[0] = strtok(line," ");
    strcpy(command,token[0]);    
    temp = strtok(NULL," ");
    while (temp != NULL)    
    {
      i = i+1;
      token[i] = temp;            
      temp = strtok(NULL," ");
    }
    char *args[i+2];
    for (j = 0; j < (i+1); j++) 
    {
      args[j] = token[j];  
    }
    args[i+1] = NULL;

    if (!strcmp("exit",command))
      exit(0);
    if (!strcmp("cd", command))
    {
      int success;
      if (success = chdir(args[1]) <0)
      {
        printf("Failed to change dir.\n");
      }
    }
    else 
    {
      int piping = 0;
      int fd;
      for (k = 0; k < sizeof args; k++)
      {         
        if (!strcmp(">",args[k])) 
        {   
          fd = open(args[k+1],O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
      if (fd <0) { printf("Open file failed.\n");}
          else 
      {
       dup2(fd, 1);
       args[k] = '\0';
       fflush(stdout);      
       close(fd);
      }
    }
    if (!strcmp("<", args[k]))
    {
      fd = open(args[k+1], O_RDONLY);
      if (fd <0) {printf("Open file failed.\n");}
      else
      {
        dup2(fd, 0);
        args[k] = '\0';
        close(fd);
      }
    }
    if (!strcmp(">>", args[k]))
    {
      fd = open(args[k+1], O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
      if (fd <0) {printf("Open file failed");}
      else
      {
            dup2(fd,1);
        args[k] = '\0';
        fflush(stdout);
        close(fd);
      }
    }
    if (!strcmp("|", args[k]))
    {
      piping = 1; 
        }
      } /*end for*/
      if (!(piping))
      {        
         pid = fork();
         if (pid <0) {}
         else if (pid == 0)
         {
           if ( (status = execvp(command, args)) < 0 )
       {
         printf("Command not found\n");
       }
         }
         else /*parent*/
         {
           wait(&status);          
         } /*end parent*/ 
      }/*end if not pipe*/
      else /*its pipe*/
      {
        int pfd[2];
    pipe(pfd);
    fd = fork();
    if (fd < 0) {}
    else if (fd ==0)
    {     
      close(pfd[1]);
      dup2(pfd[0],0);
      close(pfd[0]);
      execvp(args[2],args[2]);
    } 
    else /*parent*/
    {
      close(pfd[0]);
      dup2(pfd[1],1);
      close(pfd[1]);
      execvp(args[0],args[0]);
    }
      }/*end pipe*/
    } /*end outter else*/    

    printf("%s", prompt);

  }/*end  while*/
  return 0;
}  

1 个答案:

答案 0 :(得分:3)

for (k = 0; k < sizeof args; k++)

这不是你在args中迭代的方式:这将远远超出数组的末尾。你想要这样的东西:

num = sizeof(args) / sizeof(*args);
for (k = 0; k < num; k++)

或者,由于您将最后一个元素设置为NULL,因此可以执行

for (char **arg = args; *arg; arg++)

另请注意,您使用k进行迭代,直到数组结束,然后使用k + 1,这很可能会导致问题。