Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4823239
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类: LINUX

2010-01-16 19:11:12

/*一个简单的shell 只能执行linux命令 还不能执行脚本
执行make命令编译 得到mysh程序
*/
/*------------------ 头文件mysh.h ---------------/*
#define YES 1
#define NO 0
//一些宏定义和函数声明
char *next_cmd();
char **splitline(char *);
void freelist(char **);
void *emalloc(size_t);
void *erealloc(void *, size_t);
int execute(char **);
void fatal(char *, char *, int);
void printargs(char **);

/*------------------ mysh.c ---------------/*
#include
#include
#include
#include
#include "mysh.h"

#define DFL_PROMPT ">>" //shell的提示符
#define TRUE 1

int main()
{
    char *cmdline, *prompt, **arglist;
    int result;
   
    prompt = DFL_PROMPT;
    signal(SIGINT, SIG_IGN);
    signal(SIGQUIT, SIG_IGN); //忽略Ctrl+c信号和break信号
   
    while(TRUE)   //从标准输入读取命令
    {
        cmdline = next_cmd(prompt,stdin);
        if((cmdline == NULL) || (cmdline[0] == '\0'))
        {
            free(cmdline);
            continue;
        }   
        else if((arglist = splitline(cmdline)) != NULL)
        {
            result = execute(arglist);
            freelist(arglist);
        }
        free(cmdline);
    }
    return 0;
}

void fatal(char *s1, char *s2, int n)
{
    fprintf(stderr,"Error: %s, %s\n",s1,s2);
    exit(n);
}

/*------------------ splitline.c ---------------/*
#include
#include
#include
#include "mysh.h"

#define is_delim(x) ((x) == ' ' || (x) == '\t')
#define BUFSIZE 32

char *next_cmd(char *prompt, FILE *fp) //从标准输入读取输入命令,并保存在字符串里
{
    char *buf;    //保存输命令
    int bufspace = 0;
    int pos = 0;
    int c;
   
    printf("%s", prompt);
    while( (c = getc(fp)) != EOF )
    {
        if( c == '\n')
            break;
        if( (pos+1) >= bufspace )
        {
            if(bufspace == 0)
                buf = emalloc(BUFSIZE); //动态分配空间
            else
                buf = erealloc(buf,bufspace + BUFSIZE); //空间不足 重新分配
            bufspace += BUFSIZE;       
        }
        buf[pos++] = c;   
    }
   
    if( c = EOF && pos == 0)
         return NULL;
    buf[pos] = '\0';
    return buf;    //返回所输入的命令字符串
}

char ** splitline(char *line) //分割命令字符串,例如将“cp aaa bbb”分割成三个字符串,
{                              //存放在一个字符串数组中
    char *newstr();
    char ** args;
    int spots = 0;
    int bufspace = 0;
    int argnum = 0;
    char *cp = line;
    char *start;
    int len;
   
    if(line = NULL)
        return NULL;
    args = emalloc(BUFSIZE);
    bufspace = BUFSIZE;
    spots = BUFSIZE/sizeof(char *);
   
    while( *cp != '\0')
    {
        while( is_delim(*cp))
            cp++;
        if(*cp == '\0')
            break;
        if(argnum+1 >= spots)
        {
            args = erealloc(args, bufspace+BUFSIZE);
            bufspace += BUFSIZE;
            spots += (BUFSIZE/sizeof(char *));
        }
       
        start = cp;
        len = 1;
        while(*++cp != '\0' && !(is_delim(*cp)))
            len++;
        args[argnum++] = newstr(start, len);   
    }   
    args[argnum] = NULL;
    return args;
}

char *newstr(char *s, int l)
{
    char *rv = emalloc(l+1);
    rv[l] = '\0';
    strncpy(rv, s, l);
    return rv;
}

void freelist(char **list)
{
    char **cp = list;
    while(*cp)
        free(*cp++);
    free(list);   
}

void *emalloc(size_t n)
{
    void *rv;
    if((rv = malloc(n)) == NULL )
        fatal("out of memory", "", 1);
    return rv;   
}

void *erealloc(void *p, size_t n)
{
    void *rv;
    if((rv = realloc(p, n)) == NULL )
        fatal("realloc() failed", "", 1);
    return rv;   
}

/*------------------ execute.c ---------------/*
#include
#include
#include
#include
#include
#include

int execute(char *argv[])
{
    int pid;
    int child_info = -1;
   
    if(argv[0] == NULL)
        return 0;
    else if((strcmp(argv[0],"exit") == 0) || (strcmp(argv[0],"quit") == 0))   
        exit(0);   
    if((pid = fork()) > 0) //fork一个新进程
    {
        if(wait(&child_info) == -1) //父进程等待子进程返回
            perror("wait");
    }
    else if(pid == 0)   //子进程执行所输入的命令
    {
        signal(SIGINT, SIG_DFL);
        signal(SIGQUIT, SIG_DFL);
        execvp(argv[0], argv);
        perror("Can't execute command!");
        exit(1);
    }       
    else perror("fork");
   
    return child_info;
}

/*------------------ makefile ---------------/*
obj = mysh.o splitline.o execute.o
mysh : $(obj)
    cc -o mysh $(obj)

mysh.o splitline.o : mysh.h
execute.o :    

.PHONY : clean
clean :
    -rm $(obj) mysh
阅读(1309) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

dmastery2010-01-21 20:24:45

这个不就是Understanding Unix/linux Programming 上的例子代码吗?