我正在用c实现一个简单版本的linux shell。
我已经成功地编写了解析器,但我在派生子进程时遇到了一些问题。然而,我认为问题是由于数组、指针等原因,因为C语言刚开始使用这个项目,对它们的了解还不是很深入。
我得到了一个分段错误,不知道是从哪里来的。任何帮助都是非常感谢的。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#define MAX_COMMAND_LENGTH 250
#define MAX_ARG_LENGTH 250
typedef enum {false, true} bool;
typedef struct {
char **arg;
char *infile;
char *outfile;
int background;
} Command_Info;
int parse_cmd(char *cmd_line, Command_Info *cmd_info)
{
char *arg;
char *args[MAX_ARG_LENGTH];
int i = 0;
arg = strtok(cmd_line, " ");
while (arg != NULL) {
args[i] = arg;
arg = strtok(NULL, " ");
i++;
}
int num_elems = i;
if (num_elems == 0)
return -1;
cmd_info->infile = NULL;
cmd_info->outfile = NULL;
cmd_info->background = 0;
int iarg = 0;
for (i = 0; i < num_elems-1; i++)
{
if (!strcmp(args[i], "<"))
{
if (args[i+1] != NULL)
cmd_info->infile = args[++i];
else
return -1;
}
else if (!strcmp(args[i], ">"))
{
if (args[i+1] != NULL)
cmd_info->outfile = args[++i];
else
return -1;
}
else
cmd_info->arg[iarg++] = args[i];
}
if (!strcmp(args[i], "&"))
cmd_info->background = true;
else
cmd_info->arg[iarg++] = args[i];
cmd_info->arg[iarg] = NULL;
return 0;
}
void print_cmd(Command_Info *cmd_info)
{
int i;
for (i = 0; cmd_info->arg[i] != NULL; i++)
printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
printf("infile=\"%s\"\n", cmd_info->infile);
printf("outfile=\"%s\"\n", cmd_info->outfile);
printf("background=\"%d\"\n", cmd_info->background);
}
void get_cmd(char* str)
{
fgets(str, MAX_COMMAND_LENGTH, stdin);
str[strlen(str)-1] = '\0'; //apaga o '\n' do fim
}
pid_t exec_simple(Command_Info *cmd_info)
{
pid_t pid = fork();
if (pid < 0)
{
perror("Fork Error");
return -1;
}
if (pid == 0)
{
execvp(cmd_info->arg[0], cmd_info->arg);
perror(cmd_info->arg[0]);
exit(1);
}
return pid;
}
int main(int argc, char* argv[])
{
while (true)
{
char cmd_line[MAX_COMMAND_LENGTH];
Command_Info cmd_info;
printf(">>> ");
get_cmd(cmd_line);
if ( (parse_cmd(cmd_line, &cmd_info) == -1) )
return -1;
parse_cmd(cmd_line, &cmd_info);
if (!strcmp(cmd_info.arg[0], "exit"))
exit(0);
pid_t pid = exec_simple(&cmd_info);
waitpid(pid, NULL, 0);
}
return 0;
} 谢谢。
发布于 2010-04-16 02:13:37
问题出在cmd_info->arg,它被声明为char **arg,并且您从未为它分配过内存。
因此,当您尝试访问它来保存参数时,就像这样的cmd_info->arg[iarg++] = args[i],您正在取消引用一个未初始化的指针,从而导致分段错误。
一种解决方案是更改Command_Info结构以声明arg,如下所示:
char *arg[MAX_ARG_LENGTH];https://stackoverflow.com/questions/2647663
复制相似问题