我正在尝试使用C,Bison和Flex开发自己的shell。所有的野牛代码和flex代码都起作用,我的问题是链表。我应该能够得到野牛代码识别的参数,并将其解析为execvp(),以便执行所需的命令。我怎么做?我需要将它们解析为字符串吗?
注意:由于要在另一个函数中调用execvp(),因此我不使用参数。
输入是这样的:
./interpretador
mostra file
其中“ mostra”是我要执行的程序,“ file”是作为第二参数的文件
执行命令的代码:
case MOSTRA:
{
pid = fork();
printf("\nPID: %d\n", pid);
if (pid == 0)
{
printf("\nDone.\n ");
/*What I'm trying to do*/
if (execvp(lst->type, lst->arg1) == -1)
{
perror("\nErro no Exec\n");
}
//printf("\nexecutou\n");
exit (1);
} else if (pid < 0)
{
perror ("\nErro!");
exit(1);
}else
{
while (wait(&estado) != pid);
}
}
break;
链接列表:
command *mostra(command *lst, Value* path)
{
command *node = (command*) malloc(sizeof(command));
node->type = MOSTRA;
node->arg1 = path;
node->next = lst;
node->subCommands = NULL;
return node;
//printf("cheguei aqui");
}
shell的链表:
Interpretador *new_interpretador()
{
Interpretador *interpretador = (Interpretador*) malloc(sizeof(Interpretador));
interpretador-> vars = NULL; // no variables in the beginning
return interpretador;
}
野牛代码:
program : commandList { Launch($1); };
commandList
: command { $$ = $1; }
| command commandList { $1->next = $2; $$ = $1; }
;
command
: MT VAR_VALUE { $$ = mostra ( NULL, $2 ); }
| AP VAR_VALUE { $$ = apaga ( NULL, $2); }
| AC NAME VAR_VALUE { $$ = acrescenta ( NULL, $2, $3); }
| MAKE VAR_NAME value { $$ = insert_Make (NULL, $2, $3); }
;
value: INT { /*$$ = new_int_value($1);*/ }
| NAME { $$ = new_name($1); }
| VAR_VALUE { $$ = new_var_value($1); }
;
%%
int yyerror(char* msg) {
printf("ERROR: %s\n", msg);
return 0;
}
弹性代码:
%%
make { return MAKE; }
mostra|mt { return MT; }
[a-zA-Z0-9._-]+ { yylval.str = strdup(yytext); return VAR_VALUE; }
\$[a-z]+ { /*return VAR_NAME;*/}
[ \n\r\t] { /* ignore */ }
. { return yytext[0]; }
%%
int yywrap() { return 1; }
execvp
对您的链表实现一无所知。期望一个字符串数组,其中数组的第一个元素是程序的名称,参数从第二个元素开始,最后一个元素为NULL
。
换句话说,您需要(从链接列表中)构造一个看起来像这样的数组:
char* argv = {"mostra", "file", NULL};
以便您可以这样呼叫execvp
:
if (execvp(lst->type, argv) == -1)
或者可能
if (execvp(argv[0], argv) == -1)
因为argv数组的第一个元素通常与传递给execvp
的程序的名称相同。 (虽然不是必须的。)
注意:如果execvp
返回,则不管返回值是什么,都会出现错误。成功调用execvp
不会返回。