CSAPP - 一个简单的Shell
Posted sesiria
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSAPP - 一个简单的Shell相关的知识,希望对你有一定的参考价值。
Shell命令在是最常用的一个和操作系统交互的工具。
shell命令的基本执行过程是:
1)从stdin来读取用户的command。
2)对command进行解析,并判断是否为buildin command
3)如果是buildin command则执行buildin command
4)如果非buildin command,则执行fork命令,然后在fork的子进程中执行execve创建新的program。
其中还涉及到对输入command进行parse的简单过程。
5)如果要对进程的切换fg, bg等。需要涉及到signal切换等。(暂时不支持)
一下是一个最简单的shell, 依赖书籍csapp.c 以及 csapp.h
/* Simple Shell command
* linux>gcc -o shellex shellex.c csapp.c -lpthread
*/
#include "csapp.h"
#define MAXARGS 128
/*Function prototypes */
void eval(char *cmdline);
int parseline(char * buf, char **argv);
int builtin_command(char **argv);
int main()
{
char cmdline[MAXLINE]; /* Command line */
while(1) {
/* Read */
printf("> ");
Fgets(cmdline, MAXLINE, stdin);
if(feof(stdin))
exit(0);
/* Evaluate */
eval(cmdline);
}
}
/* eval - Evaluate a command line */
void eval(char *cmdline)
{
char *argv[MAXARGS]; /* Argument list execve() */
char buf[MAXLINE]; /* Holds modified command line */
int bg; /* Should the job run in bg or fg? */
pid_t pid; /* Process id */
strcpy(buf, cmdline);
bg = parseline(buf, argv);
if(argv[0] == NULL)
return; /* Ignore empty lines */
if(!builtin_command(argv)) {
if((pid = Fork()) == 0) { /* Child runs user job */
if(execve(argv[0], argv, environ) < 0) {
printf("%s: Command not found.\\n", argv[0]);
exit(EXIT_SUCCESS);
}
}
/* Parent waits for foreground job to terminate */
if(!bg) {
int status;
if(waitpid(pid, &status, 0) < 0)
unix_error("waitfg: waitpid error");
}
else {
printf("%d %s", pid, cmdline);
}
}
return;
}
/* If first arg is a builtin command, run it and return true */
int builtin_command(char **argv)
{
if(!strcmp(argv[0], "quit")) /* quit command */
exit(EXIT_SUCCESS);
if(!strcmp(argv[0], "&")) /* Ignore singleton & */
return 1;
return 0; /* Not a builtin command */
}
/* parseline - Parse the command line and build the argv array */
int parseline(char *buf, char ** argv)
{
char * delim; /* Points to first space delimiter */
int argc; /* Number of args */
int bg; /* Background job? */
buf[strlen(buf) - 1] = ' '; /* Replace trailing '\\n' with space */
while(*buf && (*buf == ' ')) /* Ignore leading spaces */
buf++;
/* Build the argv list */
argc = 0;
while((delim = strchr(buf, ' '))) {
argv[argc++] = buf;
*delim = '\\0';
buf = delim + 1;
while(*buf && (*buf == ' ')) /* Ignore spaces */
buf++;
}
argv[argc] = NULL;
if(argc == 0) /* Ignore blank line */
return 1;
/* Should the job run in the background? */
if((bg = (*argv[argc - 1] == '&')) != 0)
argv[--argc] = NULL;
return bg;
}
执行最简单的命令:
以上是关于CSAPP - 一个简单的Shell的主要内容,如果未能解决你的问题,请参考以下文章