【发布时间】:2015-09-30 22:40:46
【问题描述】:
我目前正在开发一个用 C 语言实现的 shell,用于我希望随着时间的推移构建的类,并且在执行我的参数时遇到了问题。我的程序使用getchar() 将条目解析为参数数组,然后使用execvp() 执行参数。我遇到的问题是重复输入参数,任何后续较短的参数都与内存中某处的字符连接。下面的例子。我需要使用getchar,它排除了获取参数的替代方法。
//Global Variables
char argument[64];
char **argv;
int main(int argc, char** argv) {
mainloop(); //Loop that calls the commands
return (EXIT_SUCCESS);
}
void prompt(){ //Modular prompt
printf ("?:");
}
void mainloop(){ //Loop that calls the functions
while(1){
prompt();
argv = (char**)malloc(sizeof(char*)*64); //allocate memory for argv
getcommand(argument, argv);
if((strcmp(argv[0],"exit" )) == 0){ //check for exit
return 0;
}
executecommand();
printcommand();
//clearcommand();
//printcommand();
}
}
void getcommand(char* argument, char** argv){ //Parser for the command
int i=0,j=0;
char c;
char* token;
while((c = getchar()) != '\n' ){ //gets char and checks for end of line
argument[i] = c;
i++;
}
token = strtok(argument, " ,."); //tokenize the command
while (token != NULL){
argv[j] = token; //pass command to array of arguments
token = strtok(NULL, " ,.");
j++;
}
//argv[j] = "\0";
}
void executecommand(){ //Function to call fork and execute with errors
pid_t childpid = fork();
int returnStatus;
if(childpid == -1){ //Fail to Fork
printf("failed to fork");
exit(1);
}
else if(childpid == 0){ //Child process
if (execvp(*argv, argv) < 0){
printf("error executing\n");
exit(1);
}
else{ //Execute successful
printf("executed");
}
}
int c=(int)waitpid(childpid, &returnStatus, 0);
if (returnStatus == 0) // Verify child process terminated without error.
{
printf("The child process terminated normally. \n");
}
if (returnStatus == 1)
{
printf("The child process terminated with an error!.\n");
}
//realloc(argv,64);
}
void printcommand(){ //Test function to print arguments
int i = 0;
while(argv[i] != NULL){
printf("Argv%d: %s \n",i, argv[i] );
i++;
}
}
/*void clearcommand(){ //Function to clear up the memory, does not work
int i=0;
argv[0] = " \0";
argv[1] = " \0";
}*/
示例输出:
?: ls -l
//functions as intended
?:echo
//argument returns as echol
任何比前一个条目短的条目都是这种情况。我不明白为什么 exec 在 '\0' 之后继续读取参数,我确信我在这里犯了内存错误。非常感谢您的帮助,我已经坚持了几天了。
【问题讨论】:
-
如果你能解释一下为什么你使用全局变量...
-
我已经编辑了你的问题。您对“C shell”的引用可能会令人困惑;它通常指的是现有的
cshshell。 -
使用原型!并且不要将
malloc和朋友的结果投射到 C 中! -
我根据您的建议删除了全局变量,感谢 Keith,我不知道这一点!