Linux08,09信号,exec,实现自己的命令解释器(待完善)

1.信号

  1. 通知进程产生了某种事件,进程可能产生某些错误。
  2. Kill发送信号9
  3. Signal可以改变信号的响应方式。1.默认,2.忽略3.自定义
  4. 看信号的地方:Usr/include/bits/signum.h
  5. 9号信号不可以改变,只可以按默认的执行。15号可以终止进程,killed是9号信号,Terminated是15号信号。
  6. 实现signal 32位 long signal长整型 发几号就把进程的pcb第几位置为1,然后查表去执行相关函数。
  7. Fork+exec实现命令解释器(bash.c)
    1①输出提示符
    ②从键盘获取将要执行的命令名字
    ③解析命令及参数,处理异常
    ④分类实现,一是内置命令(方向键如cd,exit,用which找不到的都是)二是普通命令,用fork和exec实现(注意僵死进程)
    ⑤循环不断执行输入的命令 自己实现命令(ps,kill,ls,vi,mkdir,pwd,cp)
    程序设计第五章,ls104页

2.exec

2.1替换进程,main函数的参数有三个。

3.命令解释器

3.1系统调用,库函数

系统调用在内核中实现,库函数在库里实现。

3.2myls

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 #include<dirent.h>
  6 #include<assert.h>
  7 #include<sys/stat.h>
  8 int main()
  9 {
 10     char path[256]={0};
 11     getcwd(path,256);
 12 
 13     DIR* pdir=opendir(path);
 14     if(pdir==NULL)
 15     {
 16         exit(1);
 17     }
 18 
 19     struct dirent *p=NULL;
 20     struct stat st;
 21     while((p=readdir(pdir))!=NULL)
 22     {
 23         if(strncmp(p->d_name,".",1)==0)
 24         {
 25             continue;
 26         }
 27         stat(p->d_name,&st);
 28         if(S_ISDIR(st.st_mode))
 29         {
 30             printf("\033[1;34m%s   \033[0m",p->d_name);
 31         }
 32         else
 33         {
 34             if(st.st_mode&(S_IXUSR|S_IXGRP|S_IXOTH))
 35             {
 36 
 37             printf("\033[1;32m%s   \033[0m",p->d_name);
 38             }
 39             else
 40             {
 41             printf("%s   ",p->d_name);
 42 
 43             }
 44         }
 45 
 46     }
 47     closedir(pdir);
 48     printf("\n");
 49     exit(0);
 50 }


在这里插入图片描述

3.3mykill

      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<unistd.h>
      4 #include<string.h>
      5 #include<signal.h>
      6 int main(int argc,char*argv[])
      7 {
      8     if(argc!=3)
      9     {
     10         printf("argc error\n");
     11         exit(0);
     12     }
     13     int pid=0;
     14     int sig=0;
     15     sscanf(argv[1],"%d",&pid);
     16     sscanf(argv[2],"%d",&sig);
     17     if(kill(pid,sig)!=0)
     18     {
     19         perror("kill error");
     20     }
     21     exit(0);
     22 }               

3.5su.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <pwd.h>
#include <shadow.h>
#include <termios.h>

void set_no_echo(struct termios * ster)
{
    if ( tcgetattr(0,ster) == -1 )
    {
        perror("tcgetattr error");
        return ;
    }

    struct termios tmp = *ster;
    tmp.c_lflag &= (~(ECHO | ICANON));
    
    if ( tcsetattr(0,TCSANOW,&tmp) == -1 )
    {
        perror("tcsetattr error");
    }
}

void reset_echo(struct termios * ster)
{
    if ( tcsetattr(0,TCSANOW,ster) == -1 )
    {
        perror("tcsetattr error");
    }

}

void get_user_passwd(char buff[])
{
    int i = 0;
    int ch = 0;
    
    printf("input passwd:");
    fflush(stdout);
    while( (ch = getchar()) != '\n' )
    {
        buff[i++] = ch;
        printf("*");
        fflush(stdout);
    }
}
void get_salt(const char * s, char buff[])
{
    int i = 0;
    int index = 0;
    while( *s != '\0' )
    {
        if ( *s == '$' )
        {
            index++;
            if ( index == 3 )
            {
                break;
            }
        }
        buff[i++] = *s++;
        
    }
}

int main(int argc, char* argv[])
{
    char*  puser = "root";
    if ( argc == 2 )
    {
        puser = argv[1];
    }

    struct passwd * p = getpwnam(puser);
    if ( p == NULL )
    {
        perror("su error");
        exit(1);
    }

    struct spwd  * sp = getspnam(puser);
    if ( sp == NULL )
    {
        perror("su pw error");
        exit(2);      
    }

   // printf("mima:%s\n",sp->sp_pwdp);

    char buff[128] = {0};
    struct termios ster;

    set_no_echo(&ster);
    get_user_passwd(buff);
    reset_echo(&ster);

    char salt[128] = {0};

    get_salt(sp->sp_pwdp,salt);

    char *pw = crypt(buff,salt);

    if ( strcmp(pw,sp->sp_pwdp) != 0 )
    {
        printf("passwd error\n");
        exit(1);
    }
   
    printf("success\n"); 
    

    pid_t pid = fork();
    if ( pid == -1 )
    {
        perror("su fork error");
        exit(2);
    }

    if ( pid == 0 )
    {
        setenv("HOME",p->pw_dir,1);
        setgid(p->pw_gid);
        setuid(p->pw_uid);

        execl(p->pw_shell,p->pw_shell,(char*)0);
        exit(0);
    }

    wait(NULL);

    exit(0);
}

3.5mybash

  1 #include<pwd.h>
  2 #include<dirent.h>
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<unistd.h>
  6 #include<string.h>
  7 #include<signal.h>
  8 #include<assert.h>
  9 #define LEN 10
 10 char* order[LEN]={0};
 11 void Getcomputer()
 12 {
 13     uid_t id=getuid();
 14     char *start="$";
 15     if(id==0)//root
 16      {
 17          start="#";
 18      }
 19      struct passwd * p=getpwuid(id);
 20      if(p==NULL)
 21      {
 22          printf("mybash>>");
 23          fflush(stdout);
 24          return;
 25      }
 26      char path[128]={0};
 27      getcwd(path,256);
 28      char*q="/";
 29      char*s=strtok(path,"/");
 30      while(s!=NULL)
 31      {
 32          q=s;
 33          s=strtok(NULL,"/");
 34 
 35      }
 36      char hostname[128]={0};
 37 
 38      gethostname(hostname,128);
 39     char *hostname1=strtok(hostname,".");
 40      printf("[%s@%s %smybash]%s",p->pw_name,hostname1,q,start);
 41 }
 42 char *AnalyseOrder(char*s,char *order1)
 43 {
 44     //int len =strlen(s);
 45     order1 = strtok(s, " ");
 46     int count =0;
 47     while(order1!= NULL)
 48     {
 49         order[count++] = order1;
 50         order1 = strtok(NULL, " ");
 51     }
 52     //order=strtok(s," ");
 53     return order1;
 54 }
 55 /*void myls_show(char filename[])
 56 {
 57     DIR* dir_ptr;
 58     struct dirent* direntp;
 59 
 60     if((dir_ptr=opendir(filename))==NULL)
61     {
 62         fprintf(stderr,"ls:can not open %s \n:",filename);
 63     }
 64     while((direntp=readdir(dir_ptr))!=NULL)
 65     {
 66         printf("%-10s",direntp->d_name);
 67     }
 68     closedir(dir_ptr);
 69 
 70 }
 71 int myls(int argc,char *argv[])
 72 {
 73     if(argc==1)
 74     {
 75         myls_show(".");
 76     }
 77     while(--argc)
 78     {
 79         printf("%s: \n",*++argv);
 80         myls_show(*argv);
 81         printf("\n");
 82     }
 83     return 0;
 84 }*/
 85 void mypwd ()
 86 {
 87 
 88 }
 89 void mycp()
 90 {
 91 }
 92 void myrm()
93 {
 94 }
 95 void mymv()
 96 {
 97 }
 98 void mymkdir()
 99 {
100 }
101 void myps()
102 {
103 }
104 void mysu()
105 {
106 }
107 void ExecutiveOrder(char *order)
108 {
109      if(strcmp(order,"myls")==0)
110      {
111        system("/home/yhx/study/19linux/k0224/ls");
112 
113      }
114      if(strcmp(order,"mypwd")==0)
115      {
116         mypwd();
117 
118 
119      }
120      if(strcmp(order,"mycp")==0)
121      {
122         mycp();
123      }
124      if(strcmp(order,"myrm")==0)
125      {
126          myrm();
127 
128      }
129      if(strcmp(order,"mymv")==0)
130      {
131        mymv();
132      }
133      if(strcmp(order,"mymkdir")==0)
134      {
135         mymkdir();
136      }
137      if(strcmp(order,"myps")==0)
138      {
139         myps();
140      }
141      if(strcmp(order,"mysu")==0)
142      {
143         mysu();
144      }
145 }
146 
147 int main(int argc,char *argv[])
148 {
149    while(1)
150    {
151 
152          Getcomputer();//printf("[yhx@localhost~]");
153         fflush(stdout);//刷新屏幕
154 
155         char buff[128]={0};
156          fgets(buff,128,stdin);
157 
158          buff[strlen(buff)-1]=0;//得到一个命令
159        char *order1="0";
160        order1= AnalyseOrder(buff,order1); //分析命令
161 
162         ExecutiveOrder(order1); //执行命令
163 
164          if(buff[0]==0)
165         {
166             continue;
167         }
168        /* if(strncmp(buff,"end",3)==0)
169         {
170             exit(0);
171         }*/
172     //替换
173          pid_t pid=fork();
174          assert(pid!=-1);
175 
176         if(pid==0)
177         {
178             execlp(buff,buff,(char*)0);
179             exit(0);
180         }
181 
182 
183        // if(strcmp(argv[0],"exit")==0)
184          //{
185            // break;
186          //}
187         wait(NULL);
188 //      exit(0);
189     }
190      exit(0);
191 }
                                                                                                                       


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sunshinecandy/article/details/87970486
今日推荐