shell.c
资源名称:shiyan2.rar [点击查看]
上传用户:hmmeiri
上传日期:2021-11-11
资源大小:2k
文件大小:10k
源码类别:
Shell编程
开发平台:
C/C++
- #include<stdio.h>
- #include<ctype.h>
- #include<string.h>
- #include<unistd.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<fcntl.h>
- #include<sys/wait.h>
- #include<math.h>
- #include<signal.h>
- #include<stdlib.h>
- struct command_struct{ //表示命令的结构
- char *argv[20];
- int mark; //表示输入指令类型的标记
- int numargv;//参数及指令数
- }*command;
- char *paths;
- struct path_struct{ //表路径的结构
- char *enpath[20]; //路径的数组
- int numpath; //路径数目
- }*path;
- char *command_line; //存放输入命令的字符串
- void get_command(); //解析命令函数
- void get_path(); //获得环境路径
- void common_shell(); //普通SHELL的实现
- void pipe_shell(); //实现管道
- void redirectIn_shell(); //实现输入重定向
- void redirectOut_shell();//实现输出重定向
- void back_shell(int);//实现后台
- main()
- {
- char *nowpath;
- int i;
- /*-----------------*/
- while(1){
- /*打印提示符*/
- nowpath = get_current_dir_name();
- printf("<ymf %s>", nowpath);
- command_line = (char*)malloc(100);
- gets(command_line);
- get_command();
- get_path();
- /*普通SHELL的实现*/
- if(command->mark == 0)
- {
- common_shell();
- }
- /*管道的处理*/
- if(command->mark == 1)
- {
- pipe_shell();
- }
- /*输出重定向*/
- if(command->mark == 2)
- {
- redirectOut_shell();
- }
- /*输入重定向*/
- if(command->mark == 3)
- {
- redirectIn_shell();
- }
- /*后台*/
- if(command->mark == 4)
- {
- //printf("%dn", command->mark);
- back_shell(command->mark);
- }
- }
- }
- /*实现后台的函数*/
- void back_shell(int back)
- {
- int status;
- int i, pid;
- char *p;
- /*吃掉指中'&'*/
- for(i = 0;i<command->numargv;i++)
- {
- if(strstr(command->argv[i], "&")!=NULL)
- break;
- }
- p = (char *)malloc(100);
- p = strrchr(command->argv[i], '&');
- (*p) = ' ';
- /*处理./a.out指令
- *若为./a.out则无需与环境路径相接,直接处理即可
- */
- if((strstr(command->argv[0], ".out"))!=NULL){
- pid = fork();
- if(pid == 0){
- printf("%sn", command->argv[0]);
- execvp("./a.out", command->argv);
- }
- else{
- if(back == 0)
- waitpid(pid, 0, 0);
- else
- printf("%dn", pid);
- }
- return;
- }
- //指令与环境路径相接成绝对路径
- for(i = 0;i<path->numpath;i++)
- {
- strcat(path->enpath[i], "/");
- strcat(path->enpath[i], command->argv[0]);
- //printf("%snn", path[i]);
- }
- for(i = 0;i<path->numpath;i++)
- {
- //判断该路径是否存在
- if(access(path->enpath[i], F_OK)==0){
- //创建进程
- pid = fork();
- if(pid == 0){
- //printf("child programenn");
- execvp(path->enpath[i], command->argv);
- }
- else{
- //实现后台
- if(back == 0)
- waitpid(pid, 0, 0);
- }
- }
- }
- }
- void redirectIn_shell()
- {
- int fid;
- int status;
- int i, num1;
- char *nowpath;
- char *file;
- int path_i;
- struct command_struct *command1;
- command1 = (struct command_struct *)malloc(sizeof(struct command_struct));
- for(i = 0;i<path->numpath;i++)
- {
- strcat(path->enpath[i], "/");
- strcat(path->enpath[i], command->argv[0]);
- }
- for(i = 0;i<path->numpath;i++)
- {
- if(access(path->enpath[i], F_OK)==0)
- break;
- }
- path_i = i;
- if(i==path->numpath)
- printf("error!");
- nowpath = get_current_dir_name();;
- for(i = 0;i<command->numargv;i++)
- {
- if(strstr(command->argv[i], "<")!=NULL)
- break;
- }
- num1 = i;
- file = command->argv[num1] + 1;
- strcat(nowpath, "/");
- strcat(nowpath, file);
- for(i = 0;i<num1;i++)
- {
- command1->argv[i] = command->argv[i];
- }
- if(fork() == 0)
- {
- fid = open(nowpath, O_RDONLY);
- close(0);
- dup(fid);
- close(fid);
- execvp(path->enpath[path_i], command1->argv);
- }
- else
- {
- wait(&status);
- }
- }
- void redirectOut_shell()
- {
- int fid;
- int status;
- int i, num1;
- char *nowpath;
- char *file;
- int path_i;
- struct command_struct *command1;
- command1 = (struct command_struct *)malloc(sizeof(struct command_struct));
- for(i = 0;i<path->numpath;i++)
- {
- strcat(path->enpath[i], "/");
- strcat(path->enpath[i], command->argv[0]);
- }
- for(i = 0;i<path->numpath;i++)
- {
- if(access(path->enpath[i], F_OK)==0)
- break;
- }
- path_i = i;
- if(i==path->numpath)
- printf("error!");
- nowpath = get_current_dir_name();
- for(i = 0;i<command->numargv;i++)
- {
- if(strstr(command->argv[i], ">")!=NULL)
- break;
- }
- num1 = i;
- file = command->argv[num1] + 1;
- strcat(nowpath, "/");
- strcat(nowpath, file);
- for(i = 0;i<num1;i++)
- {
- command1->argv[i] = command->argv[i];
- }
- if(fork() == 0)
- {
- fid = open(nowpath, O_WRONLY|O_CREAT);
- close(1);
- dup(fid);
- close(fid);
- execvp(path->enpath[path_i], command1->argv);
- }
- else
- {
- wait(&status);
- }
- }
- void pipe_shell()
- {
- int i, num1, j;
- int status;
- int pid[2];
- int pipe_fd[2];
- char *p;
- struct command_struct *command1,*command2;
- struct path_struct *path1, *path2;
- command1 = (struct command_struct *)malloc(sizeof(struct command_struct));
- command2 = (struct command_struct *)malloc(sizeof(struct command_struct));
- path1 = (struct path_struct*)malloc(sizeof(struct path_struct));
- path2 = (struct path_struct*)malloc(sizeof(struct path_struct));
- //printf("tmdnnn");
- for(i = 0;i<command->numargv;i++)
- {
- if(strstr(command->argv[i], "|")!=NULL)
- break;
- }
- num1 = i;
- command->argv[num1] = command->argv[num1] + 1;
- /*----------command1------------*/
- for(i = 0;i<num1;i++)
- {
- command1->argv[i] = command->argv[i];
- }
- /*-------------command2----------*/
- for(j = 0, i = num1;i<command->numargv;i++, j++)
- {
- command2->argv[j] = command->argv[i];
- //printf("%sn", command2->argv[j]);
- }
- //printf("%dnnn", j);
- //command2->argv[j + 1] = NULL;
- for(i = 0;i<path->numpath;i++)
- {
- path1->enpath[i] = (char *)malloc(50);
- strcpy(path1->enpath[i],path->enpath[i]);
- strcat(path1->enpath[i], "/");
- strcat(path1->enpath[i], command1->argv[0]);
- //printf(":::%snnn", path1->enpath[i]);
- path2->enpath[i] = (char *)malloc(50);
- strcpy(path2->enpath[i], path->enpath[i]);
- strcat(path2->enpath[i], "/");
- strcat(path2->enpath[i], command2->argv[0]);
- //printf("%snnn", path2->enpath[i]);
- }
- //查找路径
- for(i = 0;i<path->numpath;i++)
- if(access(path1->enpath[i], F_OK)==0)
- break;
- for(j = 0;j<path->numpath;j++)
- if(access(path2->enpath[j], F_OK)==0)
- break;
- //创建管道
- if(pipe(pipe_fd)<0)
- {
- printf("pipe failedn");
- exit(0);
- }
- //创建进程
- if((pid[0]=fork())<0)
- {
- printf("fork failedn");
- exit(0);
- }
- //进程1
- if(pid[0]==0)
- {
- close(pipe_fd[0]); //关闭管道输出
- dup2(pipe_fd[1], 1); //进程1输出接到管道输入端
- close(pipe_fd[1]); //关闭管道输入
- execvp(path1->enpath[i], command1->argv);//执行
- }
- if(pid[0])
- {
- if((pid[1]=fork())<0)
- {
- printf("fork failesn");
- exit(0);
- }
- if(!pid[1])
- {
- close(pipe_fd[1]);//关闭管道输入
- dup2(pipe_fd[0], 0);//进程2输入端接到管道输出端
- close(pipe_fd[0]);//关闭管道输出
- execvp(path2->enpath[j], command2->argv);
- }
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- waitpid(pid[1], &status, 0);
- }
- }
- void common_shell()
- {
- int status;
- int i;
- char *p, *nowpath;
- if((strstr(command->argv[0], ".out"))!=NULL){
- if(fork()==0){
- execvp("./a.out", command->argv);
- }
- else{
- wait(&status);
- }
- return;
- }
- //printf("%sn", path->enpath[0]);
- //printf("%sn", command->argv[0]);
- for(i = 0;i<path->numpath;i++)
- {
- strcat(path->enpath[i], "/");
- strcat(path->enpath[i], command->argv[0]);
- //printf("%snn", path[i]);
- }
- //printf("%sn", path->enpath[0]);
- //printf("%sn", command->argv[0]);
- //for(i = 0;i<path->numpath;i++)
- //printf("%sn", path->enpath[i]);
- for(i = 0;i<path->numpath;i++)
- {
- if(access(path->enpath[i], F_OK)==0)
- break;
- }
- //printf("%sn", path->enpath[i]);
- if(i == path-> numpath)
- printf("ERROR !!");
- else{
- if(fork() == 0){
- execvp(path->enpath[i], command->argv);
- }
- else{
- wait(&status);
- }
- }
- }
- void get_path()
- {
- int num, i;
- char*word;
- char *stay_pointer, *move_pointer;
- paths = (char *)getenv("PATH");
- //printf("%sn", paths);
- stay_pointer = paths;
- move_pointer = paths;
- path = (struct path_struct*)malloc(sizeof(struct path_struct));
- num = 0;
- i = 0;
- while((*move_pointer)!=' ')
- {
- stay_pointer = move_pointer;
- while((*move_pointer)!=':'&&(*move_pointer)!=' '){
- num++;
- move_pointer ++;
- }
- word = (char*)malloc(num + 1);
- strncpy(word, stay_pointer, num);
- strcat(word, "