#include <stdio.h>

#include <string.h>

#include <unistd.h>

#include <sys/wait.h>

#include <stdlib.h>



#define    CGI_NAME "get_post.ums"

#define    REQUEST_METHOD "REQUEST_METHOD=POST"

#define REQUEST_PARAMETER "myname=huangzhihui"



int main(int argc, char *argv[])

{

    int fd[2];

    if (pipe(fd) < 0)

    {

        printf("create pipe fail.\n");

    }



    pid_t pid;

    if ((pid = fork()) < 0)

    {

        printf("fork fail.\n");

    }

    else if (pid > 0)

    {

        /* parent */                

        //模拟向 CGI 传送数据

        ssize_t length = strlen(REQUEST_PARAMETER);

        if (write(fd[1], REQUEST_PARAMETER, length) != length)

        {

            printf("write error to pipe\n");

        }

        close(fd[1]);

        

        //等待CGI子进程全然把数据读取后写入,

        //实际情况应该是使用select 或者 epoll 监听

        usleep(1000);



        //模拟接收 CGI 应答的数据        

        char buff[256] = { 0 };

        length = read(fd[0], buff, sizeof(buff));

        if (length <= 0)

        {

            printf("read error from pipe\n");

        }

        else

        {

            printf("pid %d read data=%u,%s\n",getpid(),length, buff);

        }

        close(fd[0]);



        if (waitpid(pid, NULL, 0) < 0)

        {

            printf("waitpid error\n");

        }

        exit(0);

    }

    else

    {

        /* child */

       //重定向管道的输入端到标准输入

        if (fd[0] != STDIN_FILENO)

        {

            if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)

            {

                printf("dup2 error to stdin");

            }

            close(fd[0]);

        }



        //重定向管道的输出端到标准输出

        if (fd[1] != STDOUT_FILENO)

        {

            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO)

            {

                printf("dup2 error to stdout");

            }

            close(fd[1]);

        }



        //覆盖进程空间,设置CGI环境变量

        char content_length[128] = { 0 };

        sprintf(content_length, "CONTENT_LENGTH=%u", strlen(REQUEST_PARAMETER));

        char *exec_argv[3] = { REQUEST_METHOD, content_length };

        if (execve(CGI_NAME,argv,exec_argv) < 0)

        {

            printf("execl error for %s", CGI_NAME);

        }

        exit(0);

    }

    exit(0);

}

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHpoeHh4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

CGI原理解析之二------WEB服务和CGI交互数据的更多相关文章

  1. Web APi之过滤器执行过程原理解析【二】(十一)

    前言 上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要.这一节我们简单将讲述在Action方法上.控制器上.全局上以及授 ...

  2. CGI原理解析系列之中的一个----CGI怎样获取WEBserver数据

    //gcc get_post.c -o get_post.ums; #include <stdio.h> #include <stdlib.h> #include <un ...

  3. Spring源码:IOC原理解析(二)

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 接着上一章节的内容,我们来分析当new一个FileSystemXmlApplicationContext对象的时候,spring到底做了那 ...

  4. SpringBoot启动流程原理解析(二)

    在上一章我们分析了SpingBoot启动流程中实例化SpingApplication的过程. return new SpringApplication(primarySources).run(args ...

  5. RocketMQ架构原理解析(二):消息存储

    一.概述 由前文可知,RocketMQ有几个非常重要的概念: broker 服务端,负责存储.收发消息 producer 客户端1,负责产生消息 consumer 客服端2,负责消费消息 既然是消息队 ...

  6. kprobe原理解析(二)

    上一篇文章和大家简要说明了下kprobe到底应该怎样用,那么现在我们就揭开kprobe神秘的面纱,刨根问底,一睹kprobe的庐山真面目. kprobe的工作过程大致如下: 1)注册kprobe.注册 ...

  7. 骨骼蒙皮动画(Skinned Mesh)的原理解析(二)

    http://blog.csdn.net/jimoshuicao/article/details/9283071 2)蒙皮信息和蒙皮过程 2-1)Skin info的定义 上文曾讨论过,Skinned ...

  8. APPcrawler基础原理解析及使用

    一.背景 一年前,我们一直在用monkey进行Android 的稳定性测试 ,主要目的就是为了测试app 是否会产生Crash,是否会有ANR,页面错误等问题,在monkey测试过程中,实现了脱离Ca ...

  9. 如何测试Web服务.1

    一.什么是web服务  web服务在简单术语中可被定义为通过安装了特定设备或服务器到另一装置或客户端应用程序通过WWW彼此通信后的应用程序(万维网)提供的服务. Web服务通常在计算机网络的应用层上使 ...

随机推荐

  1. [51Nod]NOIP2018提高组省一冲奖班模测训练(二)

    http://www.51nod.com/contest/problemList.html#!contestId=73&randomCode=4408520896354389006 还是原题大 ...

  2. Android学习笔记进阶20之得到图片的缩略图

    <1>简介 之前往往是通过Bitmap.Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图. 现在我给大家介绍一种比较简单的方法:(网上有) 在A ...

  3. Qt之界面换肤

    简述 常用的软件基本都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,利用前面分享过的QSS系列文章,沃我们完全可以实现各种样式的定制! 简述 实现原理 效果 新建QSS文 ...

  4. java DSA Signature Sign And Verify

    SignatureSignAndVerify import java.security.KeyPair; import java.security.KeyPairGenerator; import j ...

  5. BZOJ3262: 陌上花开(三维偏序,CDQ分治)

    Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量. 定义一朵花A比另一朵花B要美 ...

  6. material风格前端CSS框架——Materialize

    官方网站:http://materializecss.com/(有中文,翻译不全) 中文学习站:http://www.materializecss.cn/(翻译较全)

  7. ArcGIS小技巧——提取面要素的质心点

    如下图,现在要做这样一件事,提取面图层中每一个图斑的质心点,然后使用质心点提取图层中的一个属性值,并在此基础上进行克里金插值,生成该属性的空间插值图.当然,今天这段文字主要简单说一下怎样提取面图层的质 ...

  8. Android学习笔记进阶十之Matrix错切变换

    刚开始我也不懂啥叫错切变换,一看效果图你就恍然大悟. 对图像的错切变换做个总结: x = x0 + b*y0; y = d*x0 + y0; 与之对应的方法是: Matrix matrix = new ...

  9. ORA-16009 remote archive log destination must be a STANDBY database

    ORA-16009错误处理 问题描述: 主备在做Switchover切换时,在切换后的备库报如下错误: Wed Jul 22 04:49:02 2015 Errors in file /u01/app ...

  10. 【2017 Multi-University Training Contest - Team 10 】Monkeys

    [链接]点击打开链接 [题意] 给你一棵n节点的树,现在让你放k个猴子,可以删边,问最少可以剩余几条边,放k个猴子,满足任意一个猴 子至少与一只猴子相连.2<=k<=n<=1e5 [ ...