管道,鸠占鹊巢

env | grep 2016查路径

捕获.PNG

写代码完成目录拷贝(注:包含子目录)

#include <stdio.h>
#include <string.h>  
#include <errno.h>  //errno
/*open   stat*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //read()   write()
/*dir ope*/
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h> //exit()

#define PER_IO_BYTES 4096

int fileType(mode_t mode)
{
    int ret = -1;
    switch (mode & S_IFMT)
    {
    case S_IFREG:
        ret = 0;
        break;
    case S_IFDIR:
        ret = 1;
        break;
    default:
        ret = -1;
        break;
    }
    return ret;
}

void copyRegFile(const char *pDestPathname
                 , const char *pSrcPathname)
{
    //对形参进行有效性检查
    if (NULL == pDestPathname || NULL == pSrcPathname)
    {
        return;
    }

    int iDestFd = -1;
    //以写的方式打开目标文件,如果不存在则创建
    iDestFd = open(pDestPathname, O_WRONLY | O_CREAT
                   , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if (-1 == iDestFd)
    {
        perror("open dest");
        exit(EXIT_FAILURE);
    }
    int iSrcFd = -1;
    //以读的方式打开源文件,如果不存在则创建
    iSrcFd = open(pSrcPathname, O_RDONLY | O_CREAT
                   , S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if (-1 == iSrcFd)
    {
        perror("open src");
        exit(EXIT_FAILURE);
    }

    unsigned char caBuf[PER_IO_BYTES] = {'\0'};
    int ret = -1;
    //从源文件循环读取数据
    while ((ret = read(iSrcFd, caBuf, PER_IO_BYTES)))
    {
        //判断数据读取成功失败与否
        if (-1 == ret)
        {
            //如果发生的错误是EAGAIN,EINTR
            //需要重新读取数据
            if (EAGAIN == errno || EINTR == errno)
            {
                continue;
            }
            //如果是其他错误,则显示错误信息并且退出程序
            perror("read src");
            //close(iSrcFd);
            //close(iDestFd);
            exit(EXIT_FAILURE);
        }
        //如果返回值为0,表示已读到文件末尾,没有数据可读
        //则文件拷贝结束
        else if (0 == ret)
        {
            break;
        }
        while (1)
        {
            //将读取到的数据写入到目标文件
            ret = write(iDestFd, caBuf, ret);
            if (-1 == ret)
            {
                if (EAGAIN == errno || EINTR == errno)
                {
                    continue;   
                }
                perror("write dest");
                //close(iSrcFd);
                //close(iDestFd);
                exit(EXIT_FAILURE);
            }
            break;
        }
    }
    close(iSrcFd);
    close(iDestFd);
}

void copyDirFile(const char *pDestDirName
                 , const char *pSrcDirName)
{
    if (NULL == pDestDirName || NULL == pSrcDirName)
    {
        return;
    }
    int ret = -1;
    //创建目录
    ret = mkdir(pDestDirName, 0775);
    if (-1 == ret)
    {
        if (EEXIST != errno)
        {
            perror("mkdir");
            exit(EXIT_FAILURE);
        }
    }
    DIR *pDestDir = NULL;
    //打开目标目录
    pDestDir = opendir(pDestDirName);
    if (NULL == pDestDir)
    {
        perror("open dest dir");
        exit(EXIT_FAILURE);
    }
    DIR *pSrcDir = NULL;
    //打开源目录
    pSrcDir = opendir(pSrcDirName);
    if (NULL == pSrcDir)
    {
        perror("open src dir");
        exit(EXIT_FAILURE);
    }
    char caDestFileName[64] = {'\0'};
    char caSrcFileName[64] = {'\0'};
    struct stat fileStat;
    struct dirent *pDirent = NULL;
    pDirent = readdir(pSrcDir);
    int iLen = 0;
    while (NULL != pDirent)
    {
        if (0 != strcmp(pDirent->d_name, "..")
            && 0 != strcmp(pDirent->d_name, "."))
        {
            //拼接路径名
            strcpy(caSrcFileName, pSrcDirName);
            iLen = strlen(pSrcDirName);
            if (pSrcDirName[iLen-1] != '/')
            {
                strcat(caSrcFileName, "/");
            }
            strcat(caSrcFileName, pDirent->d_name);
            printf("%s\n", caSrcFileName);
/********************************************************/
            strcpy(caDestFileName, pDestDirName);
            iLen = strlen(pDestDirName);
            if (pDestDirName[iLen-1] != '/')
            {
                strcat(caDestFileName, "/");
            }
            strcat(caDestFileName, pDirent->d_name);
/********************************************************/
            //获得文件status
            ret = stat(caSrcFileName, &fileStat);
            if (-1 == ret)
            {
                perror("stat");
                exit(EXIT_FAILURE);
            }
            //判断文件的类型
            ret = fileType(fileStat.st_mode);
            switch (ret)
            {
            case 0:
                copyRegFile(caDestFileName, caSrcFileName);
                break;
            case 1:
                copyDirFile(caDestFileName, caSrcFileName);
                break;
            default:
                break;
            }
        }
/********************************************************/
        pDirent = readdir(pSrcDir);
    }
}

int main(int argc, char *argv[])
{
    //copyRegFile(argv[2], argv[1]);
    copyDirFile(argv[2], argv[1]);

    return 0;
}

鸠占鹊巢(execl,ececlp,execv,execvp)

#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    int ret = -1;
    //使用新进程镜像替换当前进程镜像
    //但是当前进程的ID被新进程使用
    //-->鸠占鹊巢,巢还在,鹊变成了鸠
    //第一个参数:可执行文件的路径
    //之后的参数:可执行文件执行的方式
    //ret = execl("/bin/ls", "ls", "/usr/include", "-l", NULL);
    //ret = execl("./test", "test", NULL);
    //ret = execl("/usr/bin/gedit", "gedit", NULL);
    //ret = execl("/usr/bin/gedit", "gedit", "dirCopy.c", NULL);
    //可以不指定需要执行文件的路径
    //启动该执行文件时,到系统默认路径下去找该执行文件
    //若找到了则执行,否则出错返回
    //ret = execlp("gedit", "gedit", "dirCopy.c", NULL);
#if 0
    ret = execlp("myTest", "myTest", NULL);
    printf("ret = %d\n", ret);
    if (-1 == ret)
    {
        perror("execlp");
        return -1;
    }
#endif

    //char *const argv[] = {"ls", "/usr/include", "-l", NULL};
    //ret = execv("/bin/ls", argv);
    char *const argv[] = {"gedit", "dirCopy.c", NULL};
    ret = execvp("gedit", argv);

    return 0;
}

eg:execv

#include <stdio.h>
#include <string.h>
/*fork  exec*/
#include <unistd.h>

int main(int argc, char *argv[])
{
    pid_t pid = -1;
    pid = fork();
    if (pid > 0)  //parent
    {
        while (1) 
        {
            printf("this is parent\n");
            sleep(1);           
        }
    }
    else if (0 == pid)
    {
        //./fe /bin/ls  /usr/include -l
        int ret = -1;
        ret = execv(argv[1], argv+1);
        if (-1 == ret)
        {
            perror("execv");
            return -1;
        }
    }

    return 0;
}

运行结果:


捕获.PNG2.PNG

管道pipe

#include <unistd.h>  //pipe()  fork()
#include <stdio.h>
#include <string.h>

//通过pipe()函数创建的管道属于无名管道
//只能在父子进程间或者子进程间使用
//创建该管道的进程一旦结束,则该无名管道将会被销毁
int main(void)
{
    int pipefd[2] = {-1};
    int ret = -1;
    //创建管道,管道两端描述符存储到pipefd数组中
    //pipefd[0]表示数据流出端,可以从此端读取数据
    //pipefd[1]表示数据进入端,可以往此端写入数据
    ret = pipe(pipefd);
    if (-1 == ret)
    {
        perror("pipe");
        return -1;
    }

    pid_t pid = -1;
    //管道的创建的创建是在内核中,不独立属于进程
    //所以,fork产生子进程是并不会再次创建一个管道
    //只是对管道文件描述符进行了一次拷贝
    pid = fork();
    if (pid > 0)  //parent
    {
        close(pipefd[0]);
        while (1)
        {
            write(pipefd[1], "Hello child", 11);
            sleep(1);
        }
    }
    else if (0 == pid)  //child
    {
        close(pipefd[1]);
        char caBuf[32] = {'\0'};
        while (1)
        {
            memset(caBuf, '\0', sizeof(caBuf));
            read(pipefd[0], caBuf, 11);
            printf("%s\n", caBuf);
            sleep(1);
        }
    }
    else if (-1 == pid)  //fork failed
    {
        perror("fork");
        return -1;
    }   

    return 0;
}

eg:pipe-talk

#include <unistd.h>  //pipe()  fork()
#include <stdio.h>
#include <string.h>

int main(void)
{
    int pipefd[2] = {-1};
    int ret = -1;
    ret = pipe(pipefd);
    if (-1 == ret)
    {
        perror("pipe");
        return -1;
    }

    pid_t pid = -1;
    pid = fork();
    if (pid > 0)  //parent
    {
        int iSign = 0;
        char caBuf[64] = {'\0'};
        while (1)
        {
            memset(caBuf, '\0', sizeof(caBuf));
            if (0 == iSign)
            {
                printf("parent-input data:");
                scanf("%s", caBuf);
                write(pipefd[1], caBuf, strlen(caBuf));
                iSign = 1;
            }
            else if (1 == iSign)
            {
                read(pipefd[0], caBuf, sizeof(caBuf));
                printf("child says:%s\n", caBuf);
                iSign = 0;
            }
            sleep(1);
        }
    }
    else if (0 == pid)  //child
    {
        int iSign = 0;
        char caBuf[64] = {'\0'};
        while (1)
        {
            memset(caBuf, '\0', sizeof(caBuf));
            if (0 == iSign)
            {
                read(pipefd[0], caBuf, sizeof(caBuf));
                printf("parent says:%s\n", caBuf);
                iSign = 1;
            }
            else if (1 == iSign)
            {
                printf("child-input data:");
                scanf("%s", caBuf);
                write(pipefd[1], caBuf, strlen(caBuf));
                iSign = 0;
            }
            sleep(1);
        }
    }
    else if (-1 == pid)  //fork failed
    {
        perror("fork");
        return -1;
    }   

    return 0;
}

运行结果:

3.PNG

模仿终端

#include <stdio.h>
#include <string.h>
/*fork  exec*/
#include <unistd.h>
#include <stdlib.h>  //malloc

char *getInput(char *argv[])
{
    int ret = -1;
    int i = 0;
    char *pData = NULL;
    pData = (char *)malloc(64);
    while (EOF != scanf("%s", pData))
    {
        printf("%s\n", pData);
        argv[i] = pData;
        i++;
        pData = (char *)malloc(64);
    }
    free(pData);
    argv[i] = NULL;
    return NULL;
}

void showArgv(char *argv[])
{
    int i = 0;
    while (NULL != argv[i])
    {
        printf("%s\n", argv[i]);
        i++;
    }
}

int main(void)
{
    char *argv[32] = {NULL};
    while (1)
    {
        printf("MyTermal@sq$");
        getInput(argv);

        pid_t pid = -1;
        pid = fork();
        if (0 == pid)
        {
            int ret = -1;
            ret = execvp(argv[0], argv);
            if (-1 == ret)
            {
                perror("execv");
                return -1;
            }
        }
    }

    return 0;
}

运行结果:

捕获.PNG

atexit

#include <stdio.h>
#include <stdlib.h>  //atexit()
#include <unistd.h>  //_exit()

void fun1()
{
    printf("fun1...\n");
}
void fun2()
{
    printf("fun2...\n");
}
void fun3()
{
    printf("fun3...\n");
}
//进程正常结束时首先在用户态做一些善后工作
//然后进入内核层做一些善后工作

//return 0  exit()  会首先在用户态做一些善后工作,
//                  然后进入内核层做一些善后工作

//_exit() 直接进入内核层做一些善后工作
int main(void)
{
    //atexit注册的函数会在进程正常结束后被执行
    //执行的顺序和注册顺序相反
    atexit(fun1);
    atexit(fun2);
    atexit(fun3);

    _exit(-1);
    //abort(); //已放弃 (核心已转储): 非正常结束
    //exit(-1); //自杀

    printf("Hello World\n");
    return 0;  //寿终正寝
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • exec(鸠占鹊巢) 查找文件:fins /usr execl 模拟一个终端,可以同时打开两个文件 模拟一个终端 ...
    帅碧阅读 338评论 1 2
  • 1:InputChannel提供函数创建底层的Pipe对象 2: 1)客户端需要新建窗口 2)new ViewRo...
    自由人是工程师阅读 5,235评论 0 18
  • 本文参加#感悟三下乡,青春筑梦行#活动,本人承诺,文章内容为原创,且未在其他平台发表过。 今年的七月很特别,这...
    兰舟催发ajk阅读 592评论 3 13
  • 缘分,是一种无法用言语表达的微妙,它该来的时候,便会毫无征兆的降临 3.14 第一次遇见他,是肥肥带我去球馆打球,...
    锕娥娥娥阅读 297评论 0 1