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\n", getpid());
        else
            printf(" ID  parent : %d\n", 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\n");
    return 0;
//调用之后,不再显示printf中的内容,直接执行“hello”。

4.wait()

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

printf("child ID : %d \n",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
进程控制

posted on 2017-10-22 17:56  20155306  阅读(173)  评论(0编辑  收藏  举报

导航