Shell 用 C 编写 -- cat 命令
Shell written in C -- cat command
我正在努力学习更多关于 Unix 的知识,并且正在用 C 编写 shell。我的 execute() 命令替换了函数 system(),它适用于 ls、clear 等命令。但是,我无法让它为 cat 命令工作。相反,错误消息的数量每次都会加倍(见下文)。
==>cat
==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
a
a
这是 execute() 命令。如果我在任何使用 execute() 的地方使用 system(),cat 工作得很好,但使用 execute() 时,它就不行了。如果输入的命令只是cat
,那么args[0]
就是cat
,args[1]
就是空终止符。长度为 1。
int execute (char** args)
{
int status;
pid_t pid;
switch(pid = fork())
{
case -1:
status = -1;
fprintf(stderr, "failed to fork");
break;
case 0:
execvp(args[0], args);
fprintf(stderr,"error in child");
default:
if(!WIFSIGNALED(status) && !WIFEXITED(status))
waitpid(pid, &status, WUNTRACED);
}
return 0;
}
这就是在 main() 方法中使用 execute() 的方式。来自键盘的命令作为字符串存储在 cmndbuf 中(声明为 char cmndbuf[MAX_BUFFER]
)。然后将 cmndbuf 拆分并放入名为 splits 的新数组中。
if (cmndbuf[0]){
char** splits=malloc(sizeof(char*)*MAX_BUFFER + 1);
int i;
char* to_sep=cmndbuf;
for(i=0; i<MAX_ARGS; i++)
{
splits[i] = strsep(&to_sep, " ");
if(splits[i]==NULL) break;
}
execute(splits);
//system(cmndbuf); //this works
free(splits);
}
谢谢大家! :)
行
if(!WIFSIGNALED(status) && !WIFEXITED(status))
waitpid(pid, &status, WUNTRACED);
不会起作用,因为waitpid()至少需要执行一次,然后需要不断执行直到条件变为false。即需要一个do-while循环:
do {
wpid = waitpid(pid, &status, WUNTRACED);
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
我正在努力学习更多关于 Unix 的知识,并且正在用 C 编写 shell。我的 execute() 命令替换了函数 system(),它适用于 ls、clear 等命令。但是,我无法让它为 cat 命令工作。相反,错误消息的数量每次都会加倍(见下文)。
==>cat
==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
a
a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
==>error in child==>a
a
a
这是 execute() 命令。如果我在任何使用 execute() 的地方使用 system(),cat 工作得很好,但使用 execute() 时,它就不行了。如果输入的命令只是cat
,那么args[0]
就是cat
,args[1]
就是空终止符。长度为 1。
int execute (char** args)
{
int status;
pid_t pid;
switch(pid = fork())
{
case -1:
status = -1;
fprintf(stderr, "failed to fork");
break;
case 0:
execvp(args[0], args);
fprintf(stderr,"error in child");
default:
if(!WIFSIGNALED(status) && !WIFEXITED(status))
waitpid(pid, &status, WUNTRACED);
}
return 0;
}
这就是在 main() 方法中使用 execute() 的方式。来自键盘的命令作为字符串存储在 cmndbuf 中(声明为 char cmndbuf[MAX_BUFFER]
)。然后将 cmndbuf 拆分并放入名为 splits 的新数组中。
if (cmndbuf[0]){
char** splits=malloc(sizeof(char*)*MAX_BUFFER + 1);
int i;
char* to_sep=cmndbuf;
for(i=0; i<MAX_ARGS; i++)
{
splits[i] = strsep(&to_sep, " ");
if(splits[i]==NULL) break;
}
execute(splits);
//system(cmndbuf); //this works
free(splits);
}
谢谢大家! :)
行
if(!WIFSIGNALED(status) && !WIFEXITED(status))
waitpid(pid, &status, WUNTRACED);
不会起作用,因为waitpid()至少需要执行一次,然后需要不断执行直到条件变为false。即需要一个do-while循环:
do {
wpid = waitpid(pid, &status, WUNTRACED);
} while (!WIFEXITED(status) && !WIFSIGNALED(status));