shell命令解析器四

/* ************************************************************************
 *       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
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值