Cでシェルを作成するトラブル(SEG-FAULTとFERROR)
-
13-12-2019 - |
質問
私は自分のシェルを作る方法についてチュートリアルを追いかけていますが、今数日間立ち往生しています。
二つのこと:
- このコードがコンパイルされて実行されているとき、それはランダムにセグメンテーションの障害を持ち、なぜなぜ把握することはできません。
- if文 `IF(Ferror!= 0)`常に真実のようです。 main()関数で fgets()が失敗している理由がわからないので奇数です。
これらのトピックに関する情報(またはこのシェルの作成に関するその他のトピック)の情報は大幅に感謝されます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#define MAXSIZE 512
int parseCmd(char *cmd, char *args[])
{
printf("LOGGER: parseCmd(cmd=%s, args=%p)\n", cmd, args);
char cmdDelims[] = {' ','>'};
char *cmdReader;
cmdReader = strtok(cmd, cmdDelims);
int i = 0;
while (cmdReader != NULL)
{
args[i] = strdup(cmdReader);
printf("LOGGER: args[%d]=%s\n", i, args[i]);
cmdReader = strtok(NULL, cmdDelims);
i++;
}
return 0;
}
void printToLine(char *args[])
{
int length;
length = sizeof(args) / sizeof(char);
int i = 0;
while (i < length)
{
printf("%s\n", args[i]);
i++;
}
}
int main(int argc, char *argv[])
{
char *in;
in = malloc(MAXSIZE);
char *args[15];
char *cmd = NULL;
int errorBit = 0;
int terminationBit = 1;
char error_message[30] = "An error has occurred\n";
char inDelims[] = "\n";
while (terminationBit)
{
printf("mysh>");
// get input from command line
fgets(in, MAXSIZE, stdin);
if (ferror != 0)
{
perror(error_message);
}
// get pointer to command line input w/o the newline
cmd = strtok(in, inDelims);
// parse the command into separate arguments
errorBit = parseCmd(cmd, args);
if (errorBit)
{
perror(error_message);
exit(1);
}
printToLine(args);
// check if the user wants to exit the shell
if (strcmp(*args, "exit") == 0)
{
terminationBit = 0;
}
}
return 0;
}
.
ここにいくつかの出力があります:
**[ray@12] (6)$ mysh**
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fff4a50b080)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
Segmentation fault (core dumped)
**[ray@12] (7)$ mysh**
mysh>1 2 3 4 5 6 7 8 9 10
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3 4 5 6 7 8 9 10, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
LOGGER: args[3]=4
LOGGER: args[4]=5
LOGGER: args[5]=6
LOGGER: args[6]=7
LOGGER: args[7]=8
LOGGER: args[8]=9
LOGGER: args[9]=10
1
2
3
4
5
6
7
8
mysh>1 2 3
An error has occurred
: Success
LOGGER: parseCmd(cmd=1 2 3, args=0x7fffba053d70)
LOGGER: args[0]=1
LOGGER: args[1]=2
LOGGER: args[2]=3
1
2
3
4
5
6
7
8
.解決
ferror
エラーの場合は、ferror(stdin)
ではなくferror
をテストする必要があります。後者は関数アドレスです。これはゼロになることはありません。
if (ferror(stdin) != 0)
{
perror(error_message);
}
.
少なくともいくつかのSEGFAULTSの場合、これはあなたが思うことをしません:
length = sizeof(args) / sizeof(char);
.
これはあなたにを伝えます。ポインタの格納方法は、4または8で、 not 引数の数。
だから4つの引数(または8つの)引数がある場合は、が機能するように見えます。もっと持っているならば、それはいくつかの引数を無視しているようです。そしてそれが少ない場合は、void上で欠けている引数を取得し、(ほとんど確実な)セグメンテーション障害を引き起こします。
length
を独立して計算し、それを渡したり、args
に渡したり、ターミネーターを渡したり、最後に有効な引数を追加します。
cmdReader = strtok(NULL, cmdDelims);
i++;
}
args[i] = NULL;
return 0;
}
void printToLine(char *args[])
{
int i = 0;
while (args[i])
{
printf("%s\n", args[i]);
i++;
}
}
. 所属していません StackOverflow