/* ************************************************************************
* Filename: main.c
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#include"myinclude.h"
char *argv[20];
int main()
{
int pid;
char cmd_buf[CMD_NUM]="";
char cur_dir[DIR_NUM]="";
env_init();
while(1)
{
int i;
printf("[liman@mysh %s]#",getdir(cur_dir));
getcmd(argv,cmd_buf);
Debug(
int i=0;
Dprintf("cmd=");
while(argv[i]!=NULL)
{
Dprintf("%s ",argv[i]);
i++;
}
Dprintf("/n");
)
if(isincmd(argv)==1)
{
Dprintf("%s is in cmd!/n",argv[0]);
continue;
}
else //if((cmd=isfound(argv[0]))!=NULL)
{
if((pid=fork())<0)
{
perror("fork");
exit(1);
}
else if(pid==0)
{
i=0;
while(argv[i]!=NULL)
{
if( strncmp(argv[i],"|",1)==0 )
{
Dprintf("pipe/n");
my_pipe(i);
}
else if( strncmp(argv[i],"||",2)==0 )
{
;
}
else if( strncmp(argv[i],"|||",3)==0 )
{
printf("-bash: syntax error near unexpected token '|'/n");
}
i++;
}
exec_fun(argv);
printf("exec %s error!/n",cmd_buf);
exit(1);
}
else
{
waitpid(pid,NULL,NULL);
}
}
}
return 0;
}
/* ************************************************************************
* Filename: my_pipe.c
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#include"myinclude.h"
void my_pipe(int i)
{
pid_t pid;
int pipe_fd[2];
if(pipe(pipe_fd)<0)
{
perror("pipe");
exit(1);
}
if((pid=fork())==0)
{
argv[i]=NULL;
close(pipe_fd[0]); //关掉管道的读端
close(1);
dup2(pipe_fd[1],1); //标准输出重定向到管道的写端
execvp(argv[0],argv); //
}
else
{
close(pipe_fd[1]);
close(0);
dup2(pipe_fd[0],0); //标准输入重定向到管道的写端
execvp(argv[i+1],argv+i+1); //执行exec函数
perror("execvp more");
}
printf("my_pipe error/n");
}
/* ************************************************************************
* Filename: my_shell.c
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#include"myinclude.h"
#include"shell_fun.h"
#define OLD_DIR_NUM 100
char old_dir[OLD_DIR_NUM]="";
int isincmd(char *argv[])
{
if(strcmp(argv[0],"exit")==0)
{
printf("Byebye!/n");
exit(0);
}
else if(strcmp(argv[0],"cd")==0)
{
if(argv[1][0]=='-')
{
if(old_dir[0]==0)
{
printf("OLD_DIR is not set!");
return 1;
}
strcpy(argv[1],old_dir);
}
else if(argv[1][0]=='~')
{
if(strcmp(getlogin(),"root")==0)
{
strcpy(argv[1],"/root");
}
else
{
char dir[100]="";
strcpy(argv[1],"/home/");
strcat(argv[1],getlogin());
}
}
memset(old_dir,0,OLD_DIR_NUM);
getdir(old_dir);
if(chdir(argv[1])==0)
{
return 1;
}
else
{
printf("%s is not a dir!/n",argv[1]);
return 1;
}
}
return 0;
}
char *getdir(char *dir)
{
char *p;
memset(dir,0,DIR_NUM);
getcwd(dir,DIR_NUM);
p=strrchr(dir,'/')+1;
return p;
}
void getcmd(char*argv[],char *buf)
{
int i=0,j=0;
char ch;
char old_ch=0;
argv[j++]=buf;
memset(buf,0,CMD_NUM);
set_keypress();
while(((ch=getchar())==' ') || (ch=='/t') )
{
printf("%c",ch);;
}
while(ch != '/n')
{
printf("%c",ch);
if( (ch==' ') || (ch=='/t') )
{
if( (old_ch != ' ') && (old_ch != '/t') )
buf[i++]='/0';
}
else if( (ch=='<') || (ch=='>') )
{
if(old_ch!=ch)
{
buf[i++]='/0';
argv[j++]=buf+i;
}
if(buf[i-2]!=ch)
buf[i++]=ch;
}
else if(ch=='|')
{
if(old_ch!=ch)
{
buf[i++]='/0';
argv[j++]=buf+i;
}
buf[i++]=ch;
}
else
{
if( (old_ch==' ') || (old_ch=='/t') || (old_ch=='<') || (old_ch=='>') || (old_ch=='|') )
{
if((old_ch=='<') || (old_ch=='>') || (old_ch=='|'))
{
buf[i++]='/0';
}
buf[i++]=ch;
argv[j++]=buf+i;
}
buf[i++]=ch;
}
old_ch = ch;
ch=getchar();
}
buf[i]='/0';
argv[j]=NULL;
reset_keypress();
printf("/n");
}
void exec_fun(char *argv[])
{
char *cmd;
if( (cmd=isfound(argv[0])) !=NULL)
execv(cmd,argv);
}
/* ************************************************************************
* Filename: env_init.c
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#include"myinclude.h"
#include"env_init.h"
#define ENV_FILE "my_profile"
char *argv_env[20];
char env_buf[200];
char cur_cmd[80];
/***************************************************************
cmd参数为文件或文件路径名,
****************************************************************/
char *isfound(char* cmd)
{
int i=0;
while(argv_env[i]!=NULL)
{
memset(cur_cmd,0,80);
sprintf(cur_cmd,"%s/%s%c",argv_env[i],cmd,NULL); //把环境变量与cmd连接成完整的路径名称
if(access(cur_cmd,F_OK)==0) //调用access函数来查找文件是否存在
{
Dprintf("cur_cmd=%s/n",cur_cmd);
return cur_cmd; //如果存在返回完整的路径
}
i++;
}
return NULL;
}
/*此函数的功能是打开环境变量文件,读环境变量到buf 。 用‘:’分开PATH环境变量,并让指针数组指向切开的PATH字符串*/
void env_init()
{
FILE *fp;
int i=0;
char *p=env_buf;
if((fp=fopen(ENV_FILE,"r"))==NULL) //第一步 打开环境变量文件
{
perror("open my_profile error");
exit(1);
}
fgets(env_buf,200,fp); //第二步 获取环境变量到env_buf
fclose(fp);
printf("env_buf=%s/n",env_buf);
p=strstr(env_buf,"PATH=")+5; //第三步 指针p指向环境变量第一个字符
argv_env[i++]=p; // 第四步 用分号把PATH环境变量切开让环境变量指针数组指向每个PATH环境变量字符串。
while(*p!='/0')
{
if( (*p==':') && (*(p+1)!='/0'))
{
argv_env[i++]=p+1;
*p='/0';
}
p++;
}
argv_env[i]=NULL;
i=0;
while(argv_env[i]!=NULL)
{
Dprintf("argv_env[%d]=%s/n",i,argv_env[i++]);
}
}
/* ************************************************************************
* Filename: keypress.c
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#include "keypress.h"
static struct termios stored_settings;
void set_keypress(void)
{
struct termios new_settings;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
/* Disable canonical mode, and set buffer size to 1 byte */
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ECHO);
new_settings.c_cc[VTIME] = 0;
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
return;
}
void reset_keypress(void)
{
tcsetattr(0,TCSANOW,&stored_settings);
return;
}
/* ************************************************************************
* Filename: myinclude.h
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#ifndef __MYINCLUDE_H_
#define __MYINCLUDE_H_
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include"keypress.h"
#include"shell_fun.h"
#include"env_init.h"
#include"my_pipe.h"
#define CMD_NUM 100
#define DIR_NUM 100
extern char *argv[20];
//#define DEBUG
#ifdef DEBUG
#define Dprintf printf
#define Debug(x) {x}
#else
#define Dprintf //
/Dprintf
#define Debug(x) //
/{x}
#endif
#endif //__MYINCLUDE_H_
/* ************************************************************************
* Filename: shell_fun.h
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#ifndef __SHELL_FUN_INCLUDE_
#define __SHELL_FUN_INCLUDE_
#include"myinclude.h"
int isincmd(char *argv[]);
char *getdir(char *dir);
void getcmd(char*argv[],char *buf);
#endif //__SHELL_FUN_INCLUDE_
/* ************************************************************************
* Filename: env_init.h
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#ifndef __ENV_INIT_INCLUDE_
#define __ENV_INIT_INCLUDE_
#include"myinclude.h"
char *isfound(char* cmd);
extern char cur_cmd[80];
#endif //__ENV_INIT_INCLUDE_
/* ************************************************************************
* Filename: keypress.h
* Description:
* Version: 1.0
* Created: 2010年9月21日 11时47分58秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME ()
* Company:
* ************************************************************************/
#ifndef _INCLUDE_KEYPRESS_H_
#define _INCLUDE_KEYPRESS_H_
#include <termios.h>
void set_keypress(void);
void reset_keypress(void);
#endif //_INCLUDE_KEYPRESS_H_
* ****************************Makefile***************************************
#README:
#Use "make" to generate "mysh" without debug info
#Use "make dmysh" to generate "dmysh" with debug info
OBJECT=main.o keypress.o shell_fun.o env_init.o my_pipe.o
OBJ=main.obj keypress.obj shell_fun.obj env_init.obj my_pipe.obj
CC=gcc
CFLAG=-O2
DEBUG=-DDEBUG -g
mysh: $(OBJECT) myinclude.h
$(CC) $(CFLAG) -o $@ $(OBJECT)
%.o:%.c
$(CC) -c $(CFLAG) -o $@ $<
###########################################
#just for debug
dmysh: $(OBJ) myinclude.h
$(CC) $(CFLAG) $(DEBUG) -o $@ $(OBJ)
%.obj:%.c
$(CC) -c $(CFLAG) $(DEBUG) -o $@ $<
##########################################
.PHONY:clean
clean:
@echo Clean...
@-rm *.o *.obj mysh dmysh -f