#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. java中goto语句

    goto是java中一个保留字,但在语言中并未使用它. goto语句起源于汇编语言的程序控制,是源码级上的跳跃,这使其招致了不好的声誉,若一个程序总是从一个地方跳转到另一个地方, 还有什么办法能识别程 ...

  2. golang标准包中文手册

    golang标准包中文手册 http://files.cnblogs.com/files/rojas/liudiwu-pkgdoc-master.zip

  3. js的数据类型和typeof数据类型

    js的数据类型:number,string,null,undefined,Boolean,object typeof数据类型:number,string,object,function,undefin ...

  4. View源码分析如何创建

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 文/jj120522 博主导读:View是Android中最重要的控件,几乎所有的控件都与View相 ...

  5. 洛谷 P2655 2038年问题

    P2655 2038年问题 题目描述 网络时代,机会与危机共存.“千年虫”解决之后,会不会有新的“虫”出现?回答是肯定的,“2038年”就是一个新的关卡. 也许大家都已经知道计算机的2000年问题是什 ...

  6. POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

    Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accep ...

  7. 字串乱序 PHP&JS

    <?php /** * 字串乱序 PHP&JS * * php 中把字串乱序后输出给客户机的 JAVASCRIPT , JAVASCRIPT 中恢复 * 在指定长度提取一个字符,并把这一 ...

  8. do_pj--下拉代码脚本的使用

    接本目录 /home/zhangshuli/git2/vanzo_team/xulei/Platform.py 在~/bin目录下链接 ln -sf ~/git2/vanzo_team/xulei/P ...

  9. GitHub上常用命令(工作中几乎每天用到的命令)

    查看自己当前分支 git branch 查看远程和本地分支 git branch -a 查看origin下的分支 git config -vv git config --lis 创建分支 git br ...

  10. 软件——关于C,typedef

    1;;写博客能让我慢下来,仔细思考 1;;这篇博客大多摘自网上 1;; 不管实在C还是C++代码中,typedef这个词都不少见,当然出现频率较高的还是在C代码中.typedef与#define有些相 ...