【发布时间】:2011-12-06 22:10:22
【问题描述】:
出于学习目的,我正在尝试制作一个简单的 shell 副本(用 C 语言)。下面的代码部分显示了我现在的位置:
#define TRUE ( 1 )
#define NUMBEROFARGUMENTS ( 5 )
void execute(char** input){
pid_t pid;
pid = fork();
if (pid == 0){
printf("Spawned foreground process pid: %d\n", getpid());
execvp(input[0], input);
_exit(1);
} else {
waitpid(pid, NULL, 0);
printf("Foreground process %d terminated.\n", pid);
}
}
void check_input(char** input){
char in[70];
char *tok_inline;
gets(in);
tok_inline = strtok(in," ");
int i;
for(i=0; i < NUMBEROFARGUMENTS; i++){
input[i] = tok_inline;
tok_inline = strtok(NULL," ");
}
}
int main(){
char* input[NUMBEROFARGUMENTS];
printf("MiniShell v2.5\n");
while ( TRUE ){
printf("--> ");
check_input(input);
if ( strcmp ( input[0], "cd" ) == 0 ){
chdir(input[1]);
} else if ( strcmp( input[0], "exit" ) == 0 ){
exit(0);
} else {
execute(input);
}
}
exit(0);
}
然而,我遇到了一个我似乎无法找到答案的问题。在执行方法中执行 fork() 之后,字符串数组 input 的值似乎与分叉之前的值不同。如果我尝试在分叉之前打印出存储在输入中的字符串,一切似乎都井井有条,但在分叉后输入不再包含它应该具有的字符串,因此 execvp() 无法正确执行。
我是否遗漏了什么或者我误解了 fork() 等的工作原理?据我所知,上面的代码应该做我想做的事。
请多指教,谢谢。
【问题讨论】:
-
不要使用
gets。验证您的输入。检查您的返回值。 -
如果您所说的平台是指操作系统,那么它就是 Windows Vista。
-
Windows 不会分叉。你可能在上面使用了一些 i-wish-i-was-*nix 层,比如 Cygwin。
-
是的,我用的是Cygwin,用g++编译。
-
OP:您应该在
check_input内构建for循环,以便在strtok返回NULL时它也会终止。您还应该考虑fgets而不是gets。在我的答案中添加了一条可能值得一读的注释。