我是靠谱客的博主 飘逸砖头,最近开发中收集的这篇文章主要介绍使用fork(), pipe() 实现linux的popen, pclose功能,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

为什么要自己实现一个popenpclose函数功能呢?因为,有时系统popen打开的文件,有时会出现pclose时一直阻塞着,导致整个应用程序无法正常结束,此时使用我们自己实现的popen,则可以获得进程ID,然后通过kill该进程ID来结束popen开启的文件;

FILE*    Popen(const char* commandstr, const char* mode)
{
    pid_t pid;
    int pfd[2];
    int nRet = pipe(pfd); // 创建管道(pfd[0] 读管道,pfd[1] 写管道)
    if (-1 == nRet)
    {
        printf("error: pipe() call failsn");
        WriteLog(LOG_INFO, "[LogFileMonitor] error: pipe() call fails");
        return NULL;
    }

    pid = fork();
    if (pid < 0)
    {
        printf("error: fork() call fails.n");
        WriteLog(LOG_INFO, "[LogFileMonitor] error: fork() call fails");
        return NULL;
    }
    else if (pid == 0)
    {
        printf("I am child process, pid = %dn", getpid());
        WriteLog(LOG_INFO, "[LogFileMonitor] I am child process, pid = %d", getpid());
        // 负责写数据 --- 写管道
        close(pfd[0]);
        if (pfd[1] != STDOUT_FILENO)
        {
            dup2(pfd[1], STDOUT_FILENO); // 标准输出 指向 管道的输出文件描述符
            close(pfd[1]);
        }

        execl(SHELL, "sh", "-c", commandstr, (char *)0);
        _exit(127);
    }
    else
    {
        printf("I am parent process, pid = %dn", getpid());
        WriteLog(LOG_INFO, "[LogFileMonitor] I am parent process, pid = %d", getpid());
        // 负责读数据 --- 读管道
        close(pfd[1]);
        FILE *fp = NULL;
        if ((fp = fdopen(pfd[0], "r")) == NULL)
        {
            return NULL;
        }
        return fp;
    }
}

int     Pclose(FILE* fp)
{
    //使用非阻塞io
    int flags = 0;
    int nfd = fileno(fp);
    if (flags = fcntl(nfd, F_GETFL, 0) < 0)
    {
        LOG(LERROR) << "fcntl() get failed";
        WriteLog(LOG_ERROR, "[LogFileMonitor] fcntl() get failed");
        return false;
    }

    flags &= ~O_NONBLOCK;
    if (fcntl(nfd, F_SETFL, flags) < 0)
    {
        LOG(LERROR) << "fcntl() set noblock failed";
        WriteLog(LOG_ERROR, "[LogFileMonitor] set noblock failed");
        return false;
    }

    if (fclose(fp) == EOF)
    {
        return -1;
    }

    WriteLog(LOG_INFO, "[LogFileMonitor] Pclose() _exit(128)");
    _exit(128);
    return 0;
}

最后

以上就是飘逸砖头为你收集整理的使用fork(), pipe() 实现linux的popen, pclose功能的全部内容,希望文章能够帮你解决使用fork(), pipe() 实现linux的popen, pclose功能所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(96)

评论列表共有 0 条评论

立即
投稿
返回
顶部