shell是Unix/Linux中的重要工具,用来解析用户输入的命令。下面我们来实现一个简单的shell程序,来练习fork/exec/wait/exit的使用,顺便推荐一本书籍《Understanding Unix/Linux Programming - A Guide to Theory and Practice》,这本书写的非常好,适合Unix/Linux系统编程初学者使用。
下面是我们shell的主程序:
int main(void)
{
char *cmdline;
char *prompt;
char **arglist;
int result;
prompt = PROMPT;
signal(SIGINT, SIG_IGN);
signal(SIGQUIT,SIG_IGN);
while ((cmdline = next_cmd(prompt, stdin)) != NULL) {
if ((arglist = split_line(cmdline)) != NULL) {
result = execute(arglist);
freelist(arglist);
}
free(cmdline);
}
return ;
}
其中,next_cmd()函数的主要功能是从输入流中读入下一个命令,碰到文件结束符返回NULL。下面是该函数的代码:
char *next_cmd(char *prompt, FILE *file)
{
char *cmdline;
int length = ;
int c;
int location = ;
printf("%s", prompt);
while ((c = getc(file)) != '\n') {
if (location + >= length) {
cmdline = (char *)malloc(BUFSIZ);
length = BUFSIZ;
}
else if (location >= BUFSIZ) {
cmdline = realloc(cmdline, length + BUFSIZ);
length += BUFSIZ;
}
cmdline[location++] = c;
}
cmdline[location] = '\0';
return cmdline;
}
split_line()函数的主要功能是将输入的一行字符串拆解成字符串数组,该字符串数组以NULL结束。下面是该函数的代码:
char **split_line(char *cmd)
{
char **arglist;
int row = ;
int len = ;
char *cp = cmd;
char *start = cmd;
arglist = malloc(BUFSIZ);
while (*cp != '\0') {
while (*cp != ' ' && *cp != '\t') {
++cp;
++len;
}
arglist[row] = malloc(len + );
strncpy(arglist[row], start, len);
++row;
len = ;
while (*cp == ' ' || *cp == '\t') {
++cp;
}
start = cp;
}
arglist[row] = NULL;
return arglist;
}
execute()函数的主要功能是使用fork, execvp和wait函数来运行一个命令,并返回命令的结束状态。下面该函数的代码:
int execute(char **argv)
{
pid_t pid;
int child_info = -;
if ((pid = fork()) == -) {
perror("fork error");
}
if (pid == ) {
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
execvp(argv[], argv);
perror("exec error");
exit();
}else {
if (wait(&child_info) == -) {
perror("wait error");
}
}
return child_info;
}
freelist()函数是释放上面分配的字符串数组的空间。下面是该函数的代码:
void freelist(char **list)
{
char **cp = list;
while (*cp) {
free(*cp);
++cp;
}
free(list);
}
由于个人水平有限,欢迎讨论,非喜勿喷,thank you!!
以上就是[Linux]shell的简单实现的详细内容,更多关于[Linux]shell的简单实现的资料请关注九品源码其它相关文章!