C 写一个贝壳。使用管道执行命令时的“未初始化字节”
我正在尝试用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,它就会工作。如有任何意见,将不胜感激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测试
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);
}