WinAPI函数CreateProcess 关于创建无名管道通讯的不完美的实现

本文详细描述了如何将基于Windows IOCP模型的程序移植至Linux,特别关注于实现CreateProcess函数与无名管道支持。包括在Linux下创建无名管道的方法及与Windows的对比,以及通过复制和重定向标准输入输出来实现跨进程通信的过程。
 

问题是什么?

由于工作原因,需要移植一个基于WINDOWS IOCP模型的程序到LINUX去.由于在LINUX是没有完成端口的东西,那么这一点上面LINUX提供了我们一个叫EPOLL的网络模型.解决完这个问题,基本上我想程序应该不会有太大的移植问题了.但是当我看到ServiceManager管理器程序大篇大篇的使用WINDOWS API函数的时候,我当时简直有点失去信息了.统计出来一共30个WINDOWS API函数需要移植.大致都是和WINDOWS 服务,进程,管道相关的.世上无难事,只怕有心人.我终于下定决心.先把这个30个API函数的原形写到头文件让程序编译通过.最后再来考虑关于每个API函数实现的问题..

在我的坚定决心下,终于一个一个的实现了.但是最让我知道兴奋的一个地方是关于 实现CreateProcess函数,对无名管道的支持.. 需要移植的ServiceManager程序中 有这么一段代码,它大致想完成一个功能创建一个cmd.exe进程,然后通过管道.对cmd.exe进程的标准输入stdin 标准输出stdout进行操作.达到执行一个DOS命令的功能. 其实要完成这个也不难.在LINUX下我以前通过会采用 popen这个最简单的方式去实现它.但是为了不修改原程序的框架结构模式.我决定好好研究CreateProcess函数的功能实现..我觉得无论什么操作系统,它的基本函数都是LIBC提供的标准.那么肯定是可以实现的.为了达到目的.有幸的是阅读了VC60 IDE环境帮我在DEBUG模式下,汇编的代码.终于了解了它实现的基本原理.

我们可以通过dup 和dup2函数 来帮助我们完成这个任务.

下面我首先大致描述一下WinAPI的CreateProcess要完成的任务.

我们知道WinAPI函数CreateProcess创建一个新的进程后,可以通过倒数第二个参数si设置一个无名管道.进行2进程的通讯.

 

CreatePipe( &hPRead, &hPWrite0, &sa, 0 )

 si.hStdInput = hPRead0;
 si.hStdOutput = hPWrite0;
 si.hStdError = hPWrite0;
 si.wShowWindow = SW_HIDE;

  CreateProcess( "C;\windows\cmd.exe", NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi ) )

  我们可以通过WriteFile把 dir ,cd 等DOS命令通过一个无名管道传输给子进程cmd.exe 执行一个DOS命令.然后通过这个管道读出命令执行的结果.

 

在LINUX下面大致实现的基本方法.

代码如下:

if(pipe(pfds) == 0 )           // 创建一个无名管道.
    {
        if(fork() == 0 )
        {                                //  子进程
           close(0);               //  关闭输入描述符 0 是标准输入
           dup2(pfds[0], 0); //  把申请的pfds[0] 描述符 复制到子进程的标准输入.  (深刻理解这一步) 我现在终于明白当时在阅读LINUX 0.11代码关于这个实现的重要性了.对数据的共享.
           close(pfds[0]);      //  复制完毕,这个时候我们可以关闭申请的管道            //注意父进程中还可以使用的.

          close(1);                 // 关闭标准输 1
            dup2(pfds[1], 1); // 同样的道理
            close(pfds[1]);     // 复制完毕,关闭申请的管道,,// 父进程还可以继续使用的
           execlp("k", "k", NULL);   // 启动一个k 进程. 这个k进程是我在后面自己编写的一个代码.我本来想用sh 加参数-s来代替. 但是没成功.
        }
        else
        {
             //  父进程
           while(1)
           {
               write(pfds[1], "ls\n", 2);    //向 k 进程写命令ls\n
               sleep(1);  // 累了,休息下
                memset(buf, 0, sizeof(buf));
                read(pfds[0], buf, 32);   // 然后读一下 k进程的返回的buf.
                printf("ASD:%s\n", buf);  // 打出来让我看看
            }
        }

 k 程序的代码

  int main()
{
    char buf[32];
    while(1)
    {
        read(0, buf, 32);
        write(1, "GUOGUO\n", 7);
    }
}
程序执行的结果,会在屏幕上不断的打印出guoguo字符串.基本在LINUX下模拟CreateProcess 的实现.

先初步写这个这个,后续我会慢慢完善这篇日志.

 

 

yl.tienon@gmail.com

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值