麻烦创造C(赛格故障和ferror)外壳 [英] Trouble creating a shell in C (Seg-Fault and ferror)

查看:156
本文介绍了麻烦创造C(赛格故障和ferror)外壳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注如何使自己的壳的教程,但我一直在坚持,现在一两天。

两件事情:


  1. 当code编译并运行,它会随机有段错误,我想不出为什么。

  2. if语句`如果(FERROR!= 0)`似乎总是正确的。这是奇怪,因为我不明白为什么与fgets()未能在的main()功能。

有关这些主题(或有关创建这个壳等主题)的任何信息,将大大AP preciated。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / types.h中>#定义MAXSIZE 512INT parseCmd(字符* CMD,字符* ARGS [])
{
    的printf(记录器:parseCmd(CMD =%S,ARGS =%P)\\ n,CMD,参数);    炭cmdDelims [] = {'','>'};    字符* cmdReader;
    cmdReader = strtok的(CMD,cmdDelims);    INT I = 0;
    而(cmdReader!= NULL)
    {
        ARGS [I] =的strdup(cmdReader);        的printf(记录器:ARGS [%d个=%S \\ n,我,ARGS [I]);        cmdReader =的strtok(NULL,cmdDelims);
        我++;
    }
    返回0;
}无效printToLine(字符* ARGS [])
{
    INT长;
    长度= sizeof的(参数)/的sizeof(字符);    INT I = 0;
    而(I<长度)
    {
        的printf(%S \\ n,ARGS [I]);
        我++;
    }
}INT主(INT ARGC,CHAR *的argv [])
{
    字符*的;
    在=的malloc(MAXSIZE);    字符* ARGS [15];
    字符* CMD = NULL;    INT errorBit = 0;
    INT terminationBit = 1;
    CHAR ERROR_MESSAGE [30] =发生了错误。\\ n;    CHAR inDelims [] =\\ n;    而(terminationBit)
    {
        输出(mysh>);        //得到命令行输入
        与fgets(中,MAXSIZE,标准输入);
        如果(FERROR!= 0)
        {
            PERROR(ERROR_MESSAGE);
        }        //获取指向命令行输入W / O换行符
        CMD = strtok的(在,inDelims);        //解析命令到单独的参数
        errorBit = parseCmd(CMD,参数);
        如果(errorBit)
        {
            PERROR(ERROR_MESSAGE);
            出口(1);
        }        printToLine(参数);        //检查用户是否要退出shell
        如果(STRCMP(*指定参数时,退出)== 0)
        {
            terminationBit = 0;
        }
    }
    返回0;
}

下面是一些输出:

  ** [射线@ 12](6)$ mysh **
mysh→1 2 3
发生了错误
:成功
记录仪:parseCmd(CMD = 1 2 3,ARGS = 0x7fff4a50b080)
记录器:ARGS [0] = 1
记录器:ARGS [1] = 2
记录器:ARGS [2] = 3
1
2
3
分段错误(核心转储)
** [射线@ 12](7)$ mysh **
mysh→1 2 3 4 5 6 7 8 9 10
发生了错误
:成功
记录仪:parseCmd(CMD = 1 2 3 4 5 6 7 8 9 10,ARGS = 0x7fffba053d70)
记录器:ARGS [0] = 1
记录器:ARGS [1] = 2
记录器:ARGS [2] = 3
记录器:ARGS [3] = 4
记录器:ARGS [4] = 5
记录器:ARGS [5] = 6
记录器:ARGS [6] = 7
记录器:ARGS [7] = 8
记录器:ARGS [8] = 9
记录器:ARGS [9] = 10
1
2
3
4

6
7
8
mysh→1 2 3
发生了错误
:成功
记录仪:parseCmd(CMD = 1 2 3,ARGS = 0x7fffba053d70)
记录器:ARGS [0] = 1
记录器:ARGS [1] = 2
记录器:ARGS [2] = 3
1
2
3
4

6
7
8


解决方案

对于 FERROR 的错误,你需要测试 FERROR(标准输入),而不是 FERROR 。后者是函数的地址,这将永远是零:

 如果(FERROR(标准输入)!= 0)
{
    PERROR(ERROR_MESSAGE);
}

有关的至少一些设计缺陷,这并不做你认为:

 长度= sizeof的(参数)/的sizeof(字符);

这将告诉您的多少字节用于存储指针的,这是4个或8取决于和的的参数的数目。

所以,如果你有四个(或八个)参数,它会的显示的工作。如果您有更多的,它似乎忽略了一些争论。如果你有少,它将来自全国各地的虚空获取丢失的参数,导致(几乎可以肯定)分段错误。

您需要计算长度独立并一起传递,或者存储在 ARGS 部分终止,例如添加最后一个有效参数之后NULL参数你发现:

  cmdReader =的strtok(NULL,cmdDelims);
        我++;
    }
    ARGS [我] = NULL;
    返回0;
}无效printToLine(字符* ARGS [])
{
    INT I = 0;
    而(参数[I])
    {
        的printf(%S \\ n,ARGS [I]);
        我++;
    }
}

I have been following a tutorial on how to make my own shell but I have been stuck for a couple days now.

Two things:

  1. When this code is compiled and ran, it will randomly have segmentation faults and I cannot figure out why.
  2. The if statement `if (ferror != 0)` always seems to be true. which is odd because I do not understand why fgets() is failing in the main() function.

Any information on these topics (or other topics about creating this shell) would be greatly appreciated.

#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;
}

Here are some outputs:

**[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

解决方案

For the ferror error, you need to test ferror(stdin), not ferror. The latter is the function address, which will never be zero:

if (ferror(stdin) != 0)
{
    perror(error_message);
}

For at least some of the segfaults, this does not do what you think:

length = sizeof(args) / sizeof(char);

This will tell you how many bytes are used to store the pointer, which is 4 or 8 depending, and not the number of arguments.

So if you have four (or eight) arguments, it will appear to work. If you have more, it will seem to ignore some arguments. And if you have less, it will fetch the missing arguments from across the Void, resulting in a (almost sure) segmentation fault.

You need to calculate length independently and pass it along, or store some terminator in args, for example adding a NULL argument after the last valid argument you find:

        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++;
    }
}

这篇关于麻烦创造C(赛格故障和ferror)外壳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆