自制shell

自制shell,MINI型 http://blog.csdn.net/manio/category/218491.aspx
像普通C程序一样编译运行即可。
mini.h
/* filename:mini.h */
#define  WHITESPACE    " ., &"
#define  MAX_ARG_LEN        10
#define  MAX_DIRS           20
#define  MAX_PATH_LEN       100
#define  STD_INPUT          0
#define  STD_OUTPUT         1
#define  MAX_ARGS           5
struct  command_t {
int  argc;
char   * name;
char   * argv[MAX_ARGS];
};

mini.c
/* ***********************************************************
 *MiniShell
 *filename:mini.c
 *it's a simple shell written by Manio(maniosterATgmail.com)
 *Bugs:1.the commands must be seprated by only one whitespace
 *and more and more bugs here...
 *the part of pipe havn't be written.
 *date,addr:08/16/2006 Yangshuo,China
***********************************************************
*/
#include 
< fcntl.h >
#include 
< stdio.h >
#include 
< sys / types.h >
#include 
< sys / wait.h >
#include 
< string .h >
#include 
< unistd.h >
#include 
" mini.h "

// #define DEBUG 1 

void  printLineHead();
void  parseCommand( char   * , char   ** );
char   * GetChkFullPath( char   ** , char   ** );

main(){
int  i,j; /* for common use */
int  stat; /* used by wait() */
int  isInRedir,isOutRedir,isPipe;
int  fid; /* for file opening */
char  orginalCmd[ 100 ]; /* store the command user typed */
char   * dir[MAX_DIRS];

struct  command_t command;
char   * tempstr[ 7 ];

/* initial argv
   *maybe a error will be occured if argv is not be initialed
*/
for ( i  =   0  ; i  <  MAX_ARGS ; i ++  )
    command.argv[i] 
=  ( char   * )malloc(MAX_ARG_LEN);
    
      
while 1  ){
               printLineHead();
               gets(orginalCmd);  
/*  read user's input  */
        #ifdef DEBUG
                      printf(
" ::::after gets(orginalCmd):::: " );
                      printf(
" orginalCmd=%s " ,orginalCmd);
                      printf(
" :::::::::::::::::::::::::::::: " );
        
#endif
        
/* if "exit" inputed,exit the shell */
        
if (strcmp(orginalCmd, " exit " ==   0 )
            
break ;
        
/* devide command line to several parts */
              parseCommand(orginalCmd,command.argv);
              
/* get the amount of argv */
              
for (i  =   0 ;command.argv[i]  !=  NULL;i ++ );
              command.argc 
=  i;
#ifdef DEBUG
              printf(
" command.argc=%d " ,command.argc);
#endif
#ifdef DEBUG
    printf(
" ::::parseCommand command.argv:::: " );
    printf(
" command.name = %s " ,command.name);
    
int  commandi;
    
for (commandi = 0 ;command.argv[commandi] != NULL;commandi ++ )
        printf(
" command.argv[%d]=%s " ,commandi,command.argv[commandi]);
    printf(
" ::::END command.argv:::: " );
#endif
    
            
/* get the dirs from PATH;PATH is a enviroment var */
#ifdef DEBUG
            printf(
" getDir start=========================== " );
#endif
            getDir(dir);
            
#ifdef DEBUG
    
int  diri = 0 ;
    
for (;dir[diri] != NULL;diri ++ )
    {
        printf(
" in main dir[%d] is %s " ,diri,dir[diri]);
    }
#endif
              
/* get the name of command,this must get the full path of the file,but here is for debug */
            command.name 
=  GetChkFullPath(command.argv,dir);
#ifdef DEBUG
            printf(
" in main after GetChkFullPath command.name=%s " ,command.name);
#endif
            
if (command.name  ==  NULL ){
                
/* the command inputed is not valid or is empty */
                
continue ;
                fprintf(stderr, 
" Command %s not found " , command.argv[ 0 ]);
            }
            
/* scan  < > | ,isPipe isInRedir and isOutRedir store the position of "< > |"  */
            isPipe 
=  isInRedir  =  isOutRedir  =   0 ;
            
for ( i =   0  ; command.argv[i]  !=  NULL ; i ++  )
            {
                
if ( strcmp( command.argv[i] ,  " < "  )  ==   0  ){
                    isInRedir 
=  i;
                }
                
if ( strcmp( command.argv[i] ,  " > "  )  ==   0  ){
                    isOutRedir 
=  i;
                }
                
if ( strcmp( command.argv[i] ,   " | "  )  ==   0  ){
                    isPipe 
=  i;
                }
            }
#ifdef DEBUG
            printf(
" isin,inout,ispipe:%d%d%d " ,isInRedir,isOutRedir,isPipe);
#endif
#ifdef DEBUG
            command.argv[
3 =  NULL;
            printf(
" show the argvs which is not set " );
            
for (i  =   0  ; i  <  MAX_ARGS ; i ++ )
                printf(
" argv[%d]=%s " ,i,command.argv[i]);
#endif
                
/* excute a commmand */
        
if (fork()  ==   0 ){
#ifdef DEBUG
            printf(
" ::::::::::::::::In fork==0:::::::::::::::::: " );
#endif
            
if (isInRedir){
                fid 
=  open(command.argv[isInRedir  +   1 ],O_RDONLY);
                close(STD_INPUT);
// close standard input
                dup(fid); // redirect fid to standard input
                close(fid);
                command.argv[isInRedir] 
=  NULL;  /* ignore the word after isInRedir */
#ifdef DEBUG
    printf(
" ::::parseCommand command.argv:::: " );
    printf(
" command.name = %s " ,command.name);
    
for (commandi = 0 ;command.argv[commandi] != NULL;commandi ++ )
        printf(
" command.argv[%d]=%s " ,commandi,command.argv[commandi]);
    printf(
" ::::END command.argv:::: " );
#endif
            }
            
if (isOutRedir){
                fid 
=  open(command.argv[isOutRedir  +   1 ],O_WRONLY | O_CREAT);
                close(STD_OUTPUT);
                dup(fid);
                close(fid);
                command.argv[isOutRedir] 
=  NULL;
#ifdef DEBUG
    printf(
" ::::parseCommand command.argv:::: " );
    printf(
" command.name = %s " ,command.name);
    
for (commandi = 0 ;command.argv[commandi] != NULL;commandi ++ )
        printf(
" command.argv[%d]=%s " ,commandi,command.argv[commandi]);
    printf(
" ::::END command.argv:::: " );
#endif
            }
            execv(command.name,command.argv);
/* excute the command */
#ifdef DEBUG
            printf(
" ::::::::::::::::In fork==0 END:::::::::::::::::: " );
#endif
        }
else {
#ifdef DEBUG
            printf(
" ::::::::::::::::In fork!=0:::::::::::::::::: " );
#endif
            wait(
& stat); /* wait for the end of child process */
#ifdef DEBUG
            printf(
" ::::::::child process done!::IN FORK!=0:END::::: " );
#endif
        }
//         loopcount = 0;
      } /* while */
#ifdef DEBUG
      printf(
" Shell terminaled " );
#endif
}

void  printLineHead()
{
 printf(
"  MANIO's miniSHELL> " );     
}
/* *************************************************************
   parseCommand()
   *seprate cLine by WHITESPACE,put them to pchar[]
   *#define WHITESPACE    " ., &"
   *bugs:This code does not handle multiple WHITESPACE characters
***************************************************************
 
*/
void  parseCommand( char   * cLine,  char   * pchar[]) {
    
int  argc;
    
char   * tCLine;
    
char   ** clPtr;
//  Initialization
    tCLine  =  cLine;
    clPtr 
=   & tCLine;
    argc 
=   0 ;
//  This code does not handle multiple WHITESPACE characters
     while ((pchar[argc ++ =  strsep(clPtr, WHITESPACE))  !=  NULL); 

    pchar[argc
-- =  NULL;     //  Null terminated list of strings
}


/* ***************************************************************
   *get the path in PATH seprated by ":"
*****************************************************************
*/
int   getDir( char   * dir[])
{
    
int  i;
    
char   * s;
    
char   * oldpath;
    
char   * ppath;
    s
= ( char   * )getenv( " PATH " );
#ifdef DEBUG
    printf(
" s is %s " ,s);
    printf(
" s2=====%c " ,s[ 2 ]);
#endif
    oldpath 
=  ( char   * )malloc(strlen(s) + 1 );
    strcpy(oldpath,s);
#ifdef DEBUG
    printf(
" oldpath is %s " ,oldpath);
#endif
    ppath 
=  oldpath;
#ifdef DEBUG
    printf(
" ppath char  is %c " , * ppath);
#endif
    
    
for (i = 0 ; * ppath != ' ' ;ppath ++ )
    {
#ifdef DEBUG
    printf(
" in for ppath char  is %c " , * ppath);
#endif
        
        
if ( * ppath == ' : ' )
        {
            dir[i
++ =  oldpath;
            
* ppath = ' ' ;
            oldpath 
=  ppath + 1 ;    
        }
    }
    dir[i] 
=  NULL;
#ifdef DEBUG
    
int  diri = 0 ;
    
for (;dir[diri] != NULL;diri ++ )
    {
        printf(
" dir[%d] is %s " ,diri,dir[diri]);
    }
#endif
    
return   1 ;    
    
}

/* ***************************************************************
   *get and check the full path which the user inputed
    *dir :dirs in PATH
    *argv:argv in command_t
*****************************************************************
*/
char   * GetChkFullPath( char   ** argv, char   ** dir)
{
#ifdef DEBUG
    printf(
" :::::::::::GetChkFullPath start " );
    printf(
" argv[0]=%s dir[0]=%s " ,argv[ 0 ],dir[ 0 ]);
#endif
    
char  fullpath[MAX_PATH_LEN];
    
char   * result;
    
int  i;
    
    result 
=  NULL;
    
if * argv[ 0 !=   ' / '  )
    {
        
//  *argv[0] != '' 
#ifdef DEBUG
        printf(
" JUGE argv[0]!=/ " );
#endif
        
for (i  =   0 ;dir[i]  !=  NULL ;i ++ )
        {
            strcpy(fullpath,dir[i]);
            strcat(fullpath,
" / " );
            strcat(fullpath,argv[
0 ]);
#ifdef DEBUG
            printf(
" after strcat fullpath:%s " ,fullpath);
#endif
            
if (access(fullpath, X_OK  |  F_OK)  !=   - 1 ){
#ifdef DEBUG
                printf(
" FOUND %s in %s " ,argv[ 0 ],dir[i]);
#endif
                result 
=  ( char   * )malloc(strlen(fullpath) + 1 );
                strcpy(result,fullpath);
                
break ;
            }
        }        
    }
else {
#ifdef DEBUG
    printf(
" JUGE argv[0]==/ " );
#endif
        
if (access(argv[ 0 ], X_OK  |  F_OK)  !=   - 1 ){
#ifdef DEBUG
            printf(
" FOUND %s  " ,argv[ 0 ]);
#endif
            result 
=  ( char   * )malloc(strlen(argv[ 0 ]) + 1 );
            strcpy(result , argv[
0 ]);
        }
        
    }

    
if (result  ==  NULL ){
        printf(
" %s is not a command. " ,argv[ 0 ]);
        
return  NULL;
    }
else {
#ifdef DEBUG 
        printf(
" GetChkFullPath end result == %s " ,result);
#endif
        
return  result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值