您的位置:首页 > 运维架构 > Linux

CGI原理解析系列之三----CGI如何完整获取WEB服务器数据

2014-12-02 17:22 686 查看
 

//模拟了服务器端 httpd 进程启动 cgi的过程,

//完整展现了 get,post 方法支持

//gcc -g httpd_all.c -o httpd_all.ums;

#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 parent[2],child[2];

 if (pipe(parent) < 0)

 {

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

 }

 

 if (pipe(child) < 0)

 {

  close(parent[0]);

  close(parent[1]);

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

 }

 pid_t pid;

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

 {

  printf("fork fail.\n");

 }

 else if (pid > 0)

 {

  /* parent */

  //关闭多余的句柄,构造单一功能读写通道

  close(parent[0]);

  close(child[1]);

  

  //模拟向 CGI 传送数据

  ssize_t length = strlen(REQUEST_PARAMETER);

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

  {

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

  }

  close(parent[1]);

  

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

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

  //usleep(1000);

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

  char buff[256] = { 0 };

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

  if (length <= 0)

  {

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

  }

  else

  {

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

  }

  close(child[0]);

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

  {

   printf("waitpid error\n");

  }

  exit(0);

 }

 else

 {

  /* child */

  

  //关闭多余的句柄,构造单一功能读写通道

  close(parent[1]);

  close(child[0]);

  

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

  if (parent[0] != STDIN_FILENO)

  {

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

   {

    printf("dup2 error to stdin");

   }

   close(parent[0]);

  }

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

  if (child[1] != STDOUT_FILENO)

  {

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

   {

    printf("dup2 error to stdout");

   }

   close(child[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);

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux cgi gcc c web服务器