Linux 用C语言实现简单的shell(1)

发一波福利,操作系统的实验内容,大家可以借鉴一下,不过我的代码可能也存在一定的问题。

因为在一开始老师是一节一节课教的,当时并不知道后面还会用输入输出重定向,管道等一系列问题,我的兴趣也不在这个方面也没有预习,所以一来代码写的比较丑,二来没有对于代码进行一个合理的规划,写的也比较乱。

代码暂时实现到输入输出重定向,之后可能会加上管道处理等方面的程序。

如果让我重新写这段代码应该会规划的更好一点吧

/*author:Samsons
  date:2015.4.10*/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/wait.h>

#define MAX(100)
#define LEN(100)

char *arglist[MAX];  //shell指令参数表
int num;             //shell指令参数个数

int execute(char* arglist[])//执行外部命令
{
    int error;
    error=execvp(arglist[0],arglist);
    if (error==-1) printf("failed\n");
    exit(1);
}

char* make(char *buf)//将字符串传入参数表内
{
    char *cp;
    cp=malloc(strlen(buf)+1);
    if (cp==NULL)
    {
        fprintf(stderr,"no memory\n");
        exit(1);
    }
    strcpy(cp,buf);
    return cp;
}

int my_system(char *buf,char *arglist[])//对于字符串进行分割
{
    int num,j,i,last;
    char buffer[LEN];
    num=0;
    i=0;
    while (num<MAX)
    {
        if (buf[i]=='\n')
        {
            arglist[num]=NULL;
            return num;
        }
        if (buf[i]==' ') i++;
        last=i;
        while (buf[i]!=' ' && buf[i]!='\n') i++;
        for (j=last;j<i;j++) buffer[j-last]=buf[j];
        buffer[j-last]='\0';
        arglist[num++]=make(buffer);
    }
}
int inner(char *arglist[])//执行内置指令
{
    if (strcmp(arglist[0],"exit\0")==0)//exit
    {
        exit(0);
        return 1;
    }
    else
    if (strcmp(arglist[0],"pwd\0")==0)//pwd
    {
        char buf[LEN];
        getcwd(buf,sizeof(buf));//获得当前目录
        printf("Current dir is:%s\n",buf);
        return 1;
    }
    else
    if (strcmp(arglist[0],"cd\0")==0)//cd
    {
        char buf[LEN];
        if (chdir(arglist[1])>=0)
        {
            getcwd(buf,sizeof(buf));
            printf("Current dir is:%s\n",buf);
        }
        return 1;
    }
    else return 0;
}

void cat_in(char *q)//输入重定向
{
    char t[30];
    int fd;
    if (q[0]=='<')
    {
        strcpy(t,q+1);
        fd=open(t,O_RDONLY);
        arglist[1]=NULL;
        if (fd==-1)
        {
            printf("file open failed\n");
            return;
        }
        dup(fd,0);
        close(fd);
    }
}

void cat_out(char *q)//输出重定向
{
    char t[30];
    int fd;
    if (q[0]=='>')
    {
        strcpy(t,q+1);
        arglist[num-1]=NULL;
        num--;
        fd=open(t,O_CREAT|O_RDWR);
        if (fd==-1)
        {
            printf("file open failed\n");
            return;
        }
        dup2(fd,1);
        close(fd);
    }
}

int main()
{
    int i,pid;
    char buf[LEN];
    while (1)
    {
        fgets(buf,LEN,stdin);//读入单行指令
        num=my_system(buf,arglist);//指令分割
        int inner_flag;
        inner_flag=inner(arglist);//内置指令判断
        if (inner_flag==0)
        {
            pid=fork();//建立新的进程
            if (pid==0)
            {
                if (arglist[1]!=NULL)
                {
                    char q[LEN];
                    strcpy(q,arglist[1]);
                    cat_in(q);//输入重定向
                }
                if (arglist[num-1]!=NULL)
                {
                    char q[LEN];
                    strcpy(q,arglist[num-1]);
                    cat_out(q);//输出重定向
                }
                execute(arglist);//执行
            }
            waitpid(pid,NULL,0);
        }
    }
    return 0;
}

 

posted on 2015-04-11 12:03  samsons  阅读(8609)  评论(3编辑  收藏  举报

导航