Linux---编写自主shell. 以及两次fork

更多点子:linux—目录索引(知识小渠道)


两次fork 可以让两个进程同时运行,一次fork 只能一个运行一个阻塞
在子进程里再调一个进程,然后让儿子死亡,孙子成孤儿,之后父亲和孙子一起并发运行

#include<stdio.h>
#include<std;lib.h>
#include<string.h>
#include<sys/wait.h>
int main(void)
{
        pid_t pid = fork();
        if(pid==0)//子进程
        {
                if(fork()>0)//子进程本身,说明孙子创建失败了
                        exit(0);
                for(;;)
                {
                        printf("孙子\n");
                        sleep(1);
                }
                else
                {
                        wait(NULL);
                        for(;;)
                        {
                                printf("老子\n");
                                sleep(1);
                        }
                }
        }
}

编写xshell
WIFEXITED(status) // 如果正常退出,返回真
WEXITSTATUS(status) //如果正常退出,返回退出码
WIFSIGNALED(status) // 如果被信号打断,返回真
WTERMSIG(status) // 如果被信号打断,得到信号值

pid_t waited(pid_t pid,int *status,int options); //0 WNOHANG
pid > 0 等待进程ID等于pid的子进程死亡
pid = 0 调用者进程所在进程组的任何一个子进程死亡
pid = -1 等待任何一个子进程死亡
pid < -1 |pid|进程组的任何一个子进程死亡

exec 替换进程空间,但这不是一个函数,是一批函数,下面的enecvp只是其中的一个
进程空间替换(磁盘到虚拟):
本来进程有虚拟的空间,现在到磁盘上到一段空间,来放进程的数据
PDB不替换
int execvp(const char *file,char *const argv[]) //用file(可执行程序名)替换这个进程,占用它的空间

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<ctype.h>

void do_enecvp(int argc,char* argv[])
{
    pid_t pid=fork();
    if(pid==0)//子进程
    {
        execvp(argv[0],argv);//替换子进程,执行它
            perror("execvp");//如果命令不存在,会出错
        exit(0);//能执行到这,就说明已经出错了,退出吧
    }
    wait(NULL);//父进程等待子进程死亡,子进程是这的envp
}

void do_parse(char *buf)
{
    char *argv[8]={};
    int argc=0;
    int i;
    int status=0;
    for(i=0;buf[i]!=0;i++)//重置buf内各个的状态
    {
        if(status==0&&!isspace(buf[i]))//非空白符
        {
            argv[argc++]=buf+i;
            status=1;
        }
        else if(isspace(buf[i]))//空白符
        {
            status=0;
            buf[i]=0;//拿这把字串隔开
        }
    }
    argv[argc]=NULL;
    do_execvp(argc,argv);//让父进程等待,子进程运行,所以把它给传过去
}
int main(void)
{
    char bur[1024]={};
    while(1)
    {
        printf("my shell> ");
        memset(buf,0x00,sizeof(buf));
        while(scanf("%[~\n]%*c",buf)==0)//不接收\n,然后读取\n丢弃,如果一上来就是\n,那后面的就不读了,就会导致换行一直在输入缓存,就一直在循环
        {
            //==0说明scanf没有成功,成功的话返回2
            printf("my shell> ");
            while(getchar()!="\n");//走到这说明scanf没有成功,所以要把这一行给清空
        }
        if(strncmp(buf,"exit",4)==0)//如果输入的是exit就结束掉当前进程
            exit(0);
        do_parse(buf);
    }
}

如果有什么不对的地方,可以评论告诉我,望指导!

猜你喜欢

转载自blog.csdn.net/phonycat/article/details/79869981
今日推荐