私は自分のシェルをC言語で書こうとしています。以下のコードはパイプなしのコマンドでは動作しますが、そうでない場合は動作しません。シェルの作成。
--trace-children = yesと--track-origins = yesを使用すると、 "Syscall param execve(argv)が未初期化バイトを指しています"(以下の完全なエラーを参照)。関連する方法では
(以下makeargsを参照)valgrindのは、このライン "のargv =(CHAR *)はmalloc((+ 1カウント)*はsizeof(文字で "初期化されていない値は、ヒープ割り当てによって作成された" 私に言っています*)); "
"ls | sort"のテスト入力を使用すると、valgrindは "size 12 alloc'dのブロック"と表示します。私はlsとsortがそれぞれmakeargを呼び出すために可能な方法は見当たらず、両方とも8バイトが割り当てられなければなりません。char *には4バイト、execvpにはchar *引数配列の
このコマンドを実行すると、プログラムがハングします。
なぜこれが起こっているのか分からないのは、makeargs(パイプなし)を1回だけ呼び出すと機能するためです。どんな入力も感謝します。
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);
}
}
呼び出さメイク引数方法
int makeargs(char *s, char *** argv)
{
stripLeadingAndTrailingSpaces(s);
int k =0, count = 0;
for(k; k < strlen(s); k++)
{
if(s[k] == ' ')
count++;
}
count++;
char* parts = strtok (s," ");
strip(parts);
*argv = (char **)malloc((count+1) * sizeof(char*));
(*argv)[0] = (char *)malloc(strlen(parts)+1);
strcpy((*argv)[0], parts);
int i = 1;
for(i; i < count; i++)
{
parts = strtok (NULL, " ");
if(parts != NULL)
{
strip(parts);
(*argv)[i] = (char *)malloc(strlen(parts)+1);
strcpy((*argv)[i], parts);
}
}
(*argv)[count] = NULL;
return count;
}
valgrindの出力あなたはそこにいくつかの悪いカウントを持っている
==3603== Syscall param execve(argv) points to uninitialised byte(s)
==3603== at 0x40E2CDF: execve (execve.c:60)
==3603== by 0x40E314E: execvp (execvp.c:30)
==3603== by 0x8049069: main (cscd340_s12_hw2.c:250)
==3603== Address 0x41c617c is 4 bytes inside a block of size 12 alloc'd
==3603== at 0x4028876: malloc (vg_replace_malloc.c:236)
==3603== by 0x8049416: makeargs (ush.c:100)
==3603== by 0x8048E61: execCommand (cscd340_s12_hw2.c:191)
==3603== by 0x8049069: main (cscd340_s12_hw2.c:250)
==3603== Uninitialised value was created by a heap allocation
==3603== at 0x4028876: malloc (vg_replace_malloc.c:236)
==3603== by 0x8049416: makeargs (ush.c:100)
==3603== by 0x8048E61: execCommand (cscd340_s12_hw2.c:191)
==3603== by 0x8049069: main (cscd340_s12_hw2.c:250)
ありがとうございます。あなたの提案された構造はより良いですし、私はスペースを数えた後にカウントを追加すると思ったので、それは問題ではありませんでした。私は問題を考え出した。探してくれてありがとう。 – user1349071