A implementation of a simple unix-like shell with pure c

A implementation of a simple unix-like shell with pure c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define MAXN 1000
char* homePath,curPath[MAXN];
char *newline="\n";
char error_message[30] = "An error has occurred\n";

void mypipe(int pipepos,int argc,char **argv){
	int fd[2];
	if(pipe(fd)<0){
		write(STDERR_FILENO,error_message,strlen(error_message));
		return;
	}
	int lastpos=pipepos-1;
	while(lastpos>0 && strcmp(argv[lastpos],"|")) --lastpos;
	int pid=fork();
	switch(pid){
		case -1:
			write(STDERR_FILENO,error_message,strlen(error_message));
			break;
		case 0:
			dup2(fd[1],STDOUT_FILENO);
			close(fd[0]);
			close(fd[1]);
			if(lastpos!=0)	
				mypipe(lastpos,pipepos,argv);
			else{
				argv[pipepos]=NULL;
				if(execvp(argv[0],argv)==-1)
					write(STDERR_FILENO,error_message,strlen(error_message));
			}
			break;
		default:
			argv[argc]=NULL;
			dup2(fd[0],STDIN_FILENO);
			close(fd[0]);
			close(fd[1]);
			while(wait(NULL)>0);
			if(execvp(argv[pipepos+1],&argv[pipepos+1])==-1)
				write(STDERR_FILENO,error_message,strlen(error_message));
			break;
	}	
}

int getargs(int *argc,char **argv,char *input,int *redpos,int *pipepos){
	char *in=NULL;
	int i,j;
	int len=strlen(input);
	for(i=0;i<len;++i){
		if(input[i]=='<' || input[i]=='>' || input[i]=='&' || input[i]=='|'){
			for(j=len+2;j>i;--j)
				input[j]=input[j-2];
			input[i+1]=input[i];
			input[i+2]=' ';
			input[i]=' ';
			++i;
			len+=2;
		}
	}
	in=input;
	for(i=0;i<MAXN-1;++i){
		if((argv[i]=strtok(in," \t\n"))==NULL)
			break;
		if((!strcmp(argv[i],">") || !strcmp(argv[i],"<")) && !*redpos)
			*redpos=i;
		if(!strcmp(argv[i],"|"))
			*pipepos=i;
		in=NULL;
	}
	if(i>MAXN-1){
		write(STDERR_FILENO, error_message, strlen(error_message));
		return 0;
	}
	*argc=i;
	return 1;
}

void execute(int argc,char **argv,int redpos,int pipepos){
	int isBackGround=strcmp(argv[argc-1],"&"),stat,i;
	if(!isBackGround)
		argv[--argc]=NULL;
	if(strcmp(argv[0],"cd")==0){
		if(argc>1){
			if(chdir(argv[1])==-1){
				write(STDERR_FILENO,error_message,strlen(error_message));
				exit(1);
			}
			getcwd(curPath,MAXN);
		}
		else{
			chdir(homePath);
			getcwd(curPath,MAXN);
		}
		return;
	}
	int pid=fork();
	switch(pid){
		case -1:
			write(STDERR_FILENO,error_message,strlen(error_message));
			exit(1);
		case 0:
			for(i=0;i<argc;++i){
				if(argv[i][0]=='$' && getenv(&argv[i][1]))
					argv[i]=getenv(&argv[i][1]);
			}
			if(pipepos){
				if(redpos){
					if(argc-redpos!=2)
						write(STDERR_FILENO, error_message, strlen(error_message));
					else{
						close(STDOUT_FILENO);
						int fd=open(argv[redpos+1],O_CREAT|O_TRUNC|O_WRONLY,(S_IRWXU^S_IXUSR)|S_IRGRP|S_IROTH);
						if(fd==-1){
							write(STDERR_FILENO,error_message,strlen(error_message));
							exit(0);
						}
						argv[redpos]=NULL;
						mypipe(pipepos,argc,argv);
						exit(0);
					}
				}
				else
					mypipe(pipepos,argc,argv);
				exit(1);
			}
			if(strcmp(argv[0],"wait")==0)
				exit(0);
			else if(strcmp(argv[0],"pwd")==0){
				if(argc>1){
					write(STDERR_FILENO, error_message, strlen(error_message));
					exit(0);
				}
				write(STDOUT_FILENO,curPath,strlen(curPath));
				write(STDOUT_FILENO,newline,strlen(newline));
				exit(0);
			}
			else{
				if(!redpos && execvp(argv[0],argv)==-1){
					write(STDERR_FILENO,error_message,strlen(error_message));
					exit(0);
				}
				else{
					if(argc-redpos!=2){
						write(STDERR_FILENO,error_message,strlen(error_message));
						exit(0);
					}
					close(STDOUT_FILENO);
					int fd=open(argv[redpos+1],O_CREAT|O_TRUNC|O_WRONLY,(S_IRWXU^S_IXUSR)|S_IRGRP|S_IROTH);
					if(fd==-1){
						write(STDERR_FILENO,error_message,strlen(error_message));
						exit(0);
					}
					argv[redpos]=NULL;
					if(execvp(argv[0],argv)==-1){
						write(STDERR_FILENO,error_message,strlen(error_message));
						exit(0);
					}
				}
			}
			break;
		default:
			if(strcmp(argv[0],"wait")==0){
				if(argc!=1){
					write(STDERR_FILENO,error_message,strlen(error_message));
					break;
				}
				while(wait(&stat)>0);
				break;
			}
			else if(isBackGround)
				waitpid(pid,NULL,0);
			break;
	}
}

void start(int flag){
	char *argv[MAXN];
	char input[MAXN];
	while(1){
		if(flag)
			write(STDOUT_FILENO,"mysh > ",7);
		int argc=0,redpos=0,pipepos=0;
		int pos=0,rc;
		while(pos<MAXN-1 && (rc=read(STDIN_FILENO,&input[pos],1)) && input[pos]!='\n') ++pos;
		input[pos]='\0';
		if(pos==0 && rc==0)
			break;
		else if(pos>512){
			write(STDOUT_FILENO,input,strlen(input));
			write(STDOUT_FILENO,newline,strlen(newline));
			write(STDERR_FILENO,error_message,strlen(error_message));
			continue;
		}
		if(!flag){
			write(STDOUT_FILENO,input,strlen(input));
			write(STDOUT_FILENO,newline,strlen(newline));
		}
		if(getargs(&argc,argv,input,&redpos,&pipepos) && argc>0){
			if(strcmp(argv[0],"exit")==0){
				if(argc!=1)
					write(STDERR_FILENO, error_message, strlen(error_message));
				else break;
			}
			else execute(argc,argv,redpos,pipepos);
		}
	}
}

int main(int argc,char *argv[]){
	homePath=getenv("HOME");
	getcwd(curPath,MAXN-1);
	int i,fd;
	if(argc>1){
		for(i=1;i<argc;++i){
			if((fd=open(argv[i],O_RDONLY))==-1)
				write(STDERR_FILENO,error_message,strlen(error_message));
			else{
				dup2(fd,STDIN_FILENO);
				start(0);
			}
		}		
	}
	else 
		start(1);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值