• 2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现


    2017-2018-1 20155306 《信息安全系统设计基础》Mybash的实现


    要求:

    • 使用fork,exec,wait实现mybash
    • 写出伪代码,产品代码和测试代码
    • 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)

    知识基础:

    1.shell

    • shell命令分为 内建命令 & 外部命令

    • 内建命令(builtin command) 是shell解释程序内建的,由shell直接执行,不需要派生新的进程。

    • 外部命令分为两种: 二进制代码 或 shell脚本。shell执行外部命令时,会创建一个新的进程来执行命令。默认shell将等待直到该进程结束。
      常见的外部命令:

    grep more cat mkdir rmdir ls  sort  ftp  telnet  ssh   ps `
    
    

    2.fork()

    • fork()用来创建一个子进程,该子进程是执行该函数的父进程的一个复制的映像.
    • 注意:fork()函数有一个特点是一次调用返回两个值;
      如果返回值为0,则是子进程;如果返回值大于0,则是父进程(此时返回值就是子进程的PID);(如果返回值为-1,则创建子进程失败).
      1.用曼命令查找系统内可调用的具有创建新进程的函数:

    2.用man fork 查看函数要用的头文件以及其他用法:

    3.编写代码验证函数基本功能:

    
        pid = fork();
        if (pid < 0) {
            perror("fork failed");
            exit(1);
        }
    else{
            if(fork==0)
                printf(" ID  childs: %d
    ", getpid());
            else
                printf(" ID  parent : %d
    ", getpid() ); 
        }
    
    

    3.exec()

    • 当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。
    • 注意:exec函数只有出错的返回值而没有成功的返回值。
    1. 用 man -k execute|grep 3查看C中用于执行进程的函数,有哪些:

    2. 用man命令查看这些函数有什么不同:在[exec函数用法总结]中有非常详细的介绍(http://blog.csdn.net/zjwson/article/details/53337212)

      3.验证exce()的功能:

        char *const argv[] ={"hello", NULL};
        execv("hello", argv);
         printf("123456789
    ");
        return 0;
    //调用之后,不再显示printf中的内容,直接执行“hello”。
    

    4.wait()

    • wait系统调用会使父进程暂停执行,直到它的等待的子进程结束为止。也就是说wait是阻塞的。
    • wait可以返回两个信息,直接返回子进程的PID,还有status(注意这个值不是在子进程中调用exit函数中的退出码,下面有专门的宏使用该status)。用man命令查看其头文件和用法,用代码验证如下:
    pr=wait(NULL);
    
    printf("child ID : %d 
    ",pr);
    //wait成功后,接收到子进程的ID
    
    
    

    5.Mybash()

    代码托管

    伪代码:

    1.定义命令数组,读入用户输入的指令;
    2.定义一个结束条件,满足条件结束;否则调用wait()保证在未输入结束命令前,一直提示输入commond;
    3.调用fork函数生成一个子进程;
    4.判断fork返回值pid是否为零,如果为零调用execlp函数;如果不为零,结束;
    
    

    产品代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <wait.h>
    #include <string.h>
    
    int main() {
        char commond[50];//定义命令数组
        int pid;
        int ret;
        while (1) {//保证循环不断输入命令
            printf("commond:");
            scanf("%s", commond);
            if (strcmp(commond, "exit") == 0)//结束标志
                exit(0);
            else {
                pid = fork();
                if (pid == -1) {//创建进程失败,退出
                    printf("error ocurred!");
                    exit(0);
                } else if (pid == 0) {//创建成功,读入命令并执行
                  ret= execlp(commond, commond, NULL);
                    if (ret == -1) {//执行失败返回-1,退出,成功没有返回值
                       exit(0);
                    }
                } else {
                    wait(NULL);//等待子程序终止,防止子程序成为僵尸程序
                }
           }
    
        }
        return 0;
    }
    
    
    

    参考资料

    linux进程控制函数--fork,exec,exit,wait,sleep
    进程控制

  • 相关阅读:
    js中this指向的三种情况
    js 对象克隆方法总结(不改变原对象)
    JS 数组克隆方法总结(不可更改原数组)
    第七章、函数的基础之函数体系01
    第六篇、文件处理之文件修改的两种方式
    第六篇、文件处理之文件的高级应用
    第六篇.文件处理之python2和3字符编码的区别
    第六篇、文件处理之字符编码
    第五篇python进阶之深浅拷贝
    jquery的insertBefore(),insertAfter(),after(),before()
  • 原文地址:https://www.cnblogs.com/0831j/p/7710903.html
Copyright © 2020-2023  润新知