Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 写一个贝壳。使用管道执行命令时的“未初始化字节”_C_Shell_Exec_Fork_Pipe - Fatal编程技术网

C 写一个贝壳。使用管道执行命令时的“未初始化字节”

C 写一个贝壳。使用管道执行命令时的“未初始化字节”,c,shell,exec,fork,pipe,C,Shell,Exec,Fork,Pipe,我正在尝试用C编写自己的shell。下面的代码适用于没有管道的命令,但在其他方面则不行 使用-trace children=yes和-track origins=yes运行valgrind,给我一个Syscall参数execveargv指向未初始化的字节,请参见下面的完整错误 在相关方法中,请参见下面的makeargs valgrind告诉我,未初始化的值是由堆分配在此行argv=char*malloccount+1*sizeofchar*创建的 使用我的ls | sort valgrind测试

我正在尝试用C编写自己的shell。下面的代码适用于没有管道的命令,但在其他方面则不行

使用-trace children=yes和-track origins=yes运行valgrind,给我一个Syscall参数execveargv指向未初始化的字节,请参见下面的完整错误

在相关方法中,请参见下面的makeargs valgrind告诉我,未初始化的值是由堆分配在此行argv=char*malloccount+1*sizeofchar*创建的

使用我的ls | sort valgrind测试输入,一个大小为12的块被分配。我不明白这是怎么可能的,因为ls和sort分别调用makeargs,两者都应该分配8个字节,因为execvp在参数数组末尾需要4个字节的char*NULL和4个字节的char*NULL

执行此命令后,程序挂起

我不知道为什么会发生这种情况,因为如果只有一个调用makeargs no pipes,它就会工作。如有任何意见,将不胜感激

void execCommand(char** commandParts, int pipeCount)
{
  const int PIPE_READ = 0;
  const int PIPE_WRITE = 1;
  int numCommands = pipeCount + 1;
  int newfds[2];
  int oldfds[2];

  int k = 0;
  for(k; k < numCommands; k++)
  {

    //more commands exist
    if(k < pipeCount)
    {
      if (pipe(newfds) == -1) 
      {
        perror("new pipe error");
        exit(EXIT_FAILURE);
      }
    }

    if(fork() == 0) //child
    {
      //is prev command
      if(k > 0)
      {
        dup2(oldfds[PIPE_READ], STDIN_FILENO);
        close(oldfds[PIPE_READ]);
        close(oldfds[PIPE_WRITE]);
      }

      //more commands exist
      if(k < pipeCount)
      {
        close(newfds[PIPE_READ]);
        dup2(newfds[PIPE_WRITE], STDOUT_FILENO);
        close(newfds[PIPE_WRITE]);
      }
      char** args = NULL;
      int argcount = makeargs(commandParts[k], &args);

      if(execvp(args[0], args) == -1)
      {
        printf("%s: command not found \n", args[0]);
      }
    }
    else //parent
    {
      int status;
      waitpid(-1, &status, NULL);

      //is prev command
      if(k > 0)
      {
        close(oldfds[PIPE_READ]);
        close(oldfds[PIPE_WRITE]);
      }
      //more commands exist
      if(k < pipeCount)
      {
        oldfds[PIPE_READ] = newfds[PIPE_READ];
        oldfds[PIPE_WRITE] = newfds[PIPE_WRITE];
      }
    }
    //there are pipes
    if(pipeCount > 0 && k > 0)
    {
      close(newfds[PIPE_READ]);
      close(newfds[PIPE_WRITE]);
    } 
    //   if(argcount > 0)
    //    cleanArgs(argcount, args);   
  }
}

这里的计数有些错误:count是空格数,而不是命令行中的单词数。这会影响复制代码:

for(i; i < count; i++)
{
  parts = strtok (NULL, " ");
  if(parts != NULL)
  {
    ...
  }
}

最后,我把问题追溯到我的StripLeading和TrailingSpaces

我有

但需要

void stripLeadingAndTrailingSpaces(char temp[]) 
{
   int len = strlen(temp)+1, start = 0;  
   while(isspace(temp[len-2]))
   {
      temp[len-2] = '\0';
      len--;
   }
   while(isspace(temp[start]))
   {
      start++;
      len--;
   }  
   memmove(temp, temp + start, len);
}
旧条带法存在几个问题:

我正在检查“/0”以查看结尾是否是空格。 我没有将新的空终止符应用到新的端点。 我没有减少长度时,削减空间的前面。
谢谢你的意见。你建议的结构比我的好,我想我会在计算完空间后再加一个来计算,所以这不是问题所在。不过我还是解决了问题。谢谢你的关注。
for(i; i < count; i++)
{
  parts = strtok (NULL, " ");
  if(parts != NULL)
  {
    ...
  }
}
for(i; i <= count; i++)
{
  parts = strtok (NULL, " ");
  if(parts != NULL)
  {
    ... // consider using strdup
  }
  else
  {
    (*argv)[i] = NULL;
    break;
  }
}
void stripLeadingAndTrailingSpaces(char temp[]) 
{
   int len = strlen(temp), start = 0;  
   while(isspace(temp[len]))
   {
      len--;
   }
   while(isspace(temp[start]))
   {
      start++;
   }  
   memmove(temp, temp + start, len);
}
void stripLeadingAndTrailingSpaces(char temp[]) 
{
   int len = strlen(temp)+1, start = 0;  
   while(isspace(temp[len-2]))
   {
      temp[len-2] = '\0';
      len--;
   }
   while(isspace(temp[start]))
   {
      start++;
      len--;
   }  
   memmove(temp, temp + start, len);
}