全部博文(930)
分类: LINUX
2010-01-16 19:11:12
/*一个简单的shell 只能执行linux命令 还不能执行脚本 执行make命令编译 得到mysh程序 */ /*------------------ 头文件mysh.h ---------------/* #define YES 1 #define NO 0 //一些宏定义和函数声明 char *next_cmd(); char **splitline(char *); void freelist(char **); void *emalloc(size_t); void *erealloc(void *, size_t); int execute(char **); void fatal(char *, char *, int); void printargs(char **); /*------------------ mysh.c ---------------/* #include #include #include #include #include "mysh.h" #define DFL_PROMPT ">>" //shell的提示符 #define TRUE 1 int main() { char *cmdline, *prompt, **arglist; int result; prompt = DFL_PROMPT; signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); //忽略Ctrl+c信号和break信号 while(TRUE) //从标准输入读取命令 { cmdline = next_cmd(prompt,stdin); if((cmdline == NULL) || (cmdline[0] == '\0')) { free(cmdline); continue; } else if((arglist = splitline(cmdline)) != NULL) { result = execute(arglist); freelist(arglist); } free(cmdline); } return 0; } void fatal(char *s1, char *s2, int n) { fprintf(stderr,"Error: %s, %s\n",s1,s2); exit(n); } /*------------------ splitline.c ---------------/* #include #include #include #include "mysh.h" #define is_delim(x) ((x) == ' ' || (x) == '\t') #define BUFSIZE 32 char *next_cmd(char *prompt, FILE *fp) //从标准输入读取输入命令,并保存在字符串里 { char *buf; //保存输命令 int bufspace = 0; int pos = 0; int c; printf("%s", prompt); while( (c = getc(fp)) != EOF ) { if( c == '\n') break; if( (pos+1) >= bufspace ) { if(bufspace == 0) buf = emalloc(BUFSIZE); //动态分配空间 else buf = erealloc(buf,bufspace + BUFSIZE); //空间不足 重新分配 bufspace += BUFSIZE; } buf[pos++] = c; } if( c = EOF && pos == 0) return NULL; buf[pos] = '\0'; return buf; //返回所输入的命令字符串 } char ** splitline(char *line) //分割命令字符串,例如将“cp aaa bbb”分割成三个字符串, { //存放在一个字符串数组中 char *newstr(); char ** args; int spots = 0; int bufspace = 0; int argnum = 0; char *cp = line; char *start; int len; if(line = NULL) return NULL; args = emalloc(BUFSIZE); bufspace = BUFSIZE; spots = BUFSIZE/sizeof(char *); while( *cp != '\0') { while( is_delim(*cp)) cp++; if(*cp == '\0') break; if(argnum+1 >= spots) { args = erealloc(args, bufspace+BUFSIZE); bufspace += BUFSIZE; spots += (BUFSIZE/sizeof(char *)); } start = cp; len = 1; while(*++cp != '\0' && !(is_delim(*cp))) len++; args[argnum++] = newstr(start, len); } args[argnum] = NULL; return args; } char *newstr(char *s, int l) { char *rv = emalloc(l+1); rv[l] = '\0'; strncpy(rv, s, l); return rv; } void freelist(char **list) { char **cp = list; while(*cp) free(*cp++); free(list); } void *emalloc(size_t n) { void *rv; if((rv = malloc(n)) == NULL ) fatal("out of memory", "", 1); return rv; } void *erealloc(void *p, size_t n) { void *rv; if((rv = realloc(p, n)) == NULL ) fatal("realloc() failed", "", 1); return rv; } /*------------------ execute.c ---------------/* #include #include #include #include #include #include int execute(char *argv[]) { int pid; int child_info = -1; if(argv[0] == NULL) return 0; else if((strcmp(argv[0],"exit") == 0) || (strcmp(argv[0],"quit") == 0)) exit(0); if((pid = fork()) > 0) //fork一个新进程 { if(wait(&child_info) == -1) //父进程等待子进程返回 perror("wait"); } else if(pid == 0) //子进程执行所输入的命令 { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); execvp(argv[0], argv); perror("Can't execute command!"); exit(1); } else perror("fork"); return child_info; } /*------------------ makefile ---------------/* obj = mysh.o splitline.o execute.o mysh : $(obj) cc -o mysh $(obj) mysh.o splitline.o : mysh.h execute.o : .PHONY : clean clean : -rm $(obj) mysh |