我需要一些关于类的简单shell的帮助,我担心我不太明白execvp()函数是如何工作的。
shell不做太多,不支持管道,重定向,脚本或类似的任何东西。它只读取命令,读入选项(使用命令作为选项[0])和分叉。
它工作了几次,然后开始给我一些关于无法找到命令的错误。此处发布的其他类似问题与管道或重定向有关。
请原谅noobcode,它不漂亮,但我希望它清晰可读:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#define OPT_AMT 10
const size_t SIZE = 256;
int i = 0;
int o = 0;
int main(void) {
// initializing data
int exit = 0;
char cwd[SIZE];
char cmd[SIZE];
char input[SIZE * OPT_AMT];
char *opt[OPT_AMT];
getcwd(cwd, SIZE);
// main loop
while (exit == 0) {
// reset everything
o = 1;
i = 0;
cmd[0] = "\0";
while (i < OPT_AMT) {
opt[i++] = "\0";
}
// get input
printf("%s $ ", cwd);
scanf("%s", cmd);
gets(input);
opt[0] = cmd;
char *t = strtok(input, " ");
while (t != NULL) {
opt[o++] = t;
t = strtok(NULL, " ");
}
// if exit, exit
if (strcmp(cmd, "exit") == 0) {
exit = 1;
}
// else fork and execute
else {
pid_t pID = fork();
if (pID == 0) { // child process
execvp(cmd, opt);
} else if (pID < 0) { // failed to fork
printf("\nFailed to fork\n");
} else { // parent process
wait(0);
}
}
}
// cleanup
printf("\nFinished! Exiting...\n");
return 0;
}
有什么明显的错误吗?我最近添加了退出条件和重置选项数组。
另外,这是我的第一个问题,所以提醒我可能已经破坏的任何规则。
答案 0 :(得分:2)
首先,这个
cmd[0] = "\0";
应该是
cmd[0] = '\0';
听取编译器的警告。
要启用它们,请使用选项-Wall -Wextra -pedantic
(对于gcc)。
另外,您可能最好将opt
的元素初始化为“无”,即NULL
,但文字为"\0"
:
while (i < OPT_AMT) {
opt[i++] = NULL;
}
由于execvp()
要求opt
为NULL
- 已终止的C-“字符串数组”(感谢Paul提及/措辞相关背景)。
另外^ 2:不要使用gets()
,因为它是邪恶的,甚至不再是C标准的一部分。而不是
gets(input);
使用
fgets(input, sizeof input, stdin);
gets()
很容易让用户溢出传递的(输入)缓冲区。 (没有保罗就提到我的想法,顺便说一下......; - ))