当前位置: 代码迷 >> CGI >> cgi上dup2()有关问题
  详细解决方案

cgi上dup2()有关问题

热度:537   发布时间:2012-08-03 00:12:14.0
cgi下dup2()问题

函数名: dup2
功 能: 复制文件句柄
用 法: int dup2(int oldhandle, int newhandle);

#include <unistd.h>

define STDIN_FILENO    0       /* Standard input.  */
#define STDOUT_FILENO   1       /* Standard output.  */
#define STDERR_FILENO   2       /* Standard error output.  */

问题描述:

在写一个小型web服务器的过程中,把返回的socket描述符sockfd用dup2函数复制给标准输出描述符,这样才调用cgi程序的时候对于所有原本要输出到标准输出的流全部都会写入到sockfd,返回给客户端。但是有一个问题:就是我想用lsz来传输一个文件,客户端一直没有返回。我查看了下进程,发现一直都卡在lsz里面的。我想了很久,发现 lsz 发送文件的过程中会有输出,这时候打输出就默认输出到sockfd里面了,导致我程序死了。也就是说怎么样实现cgi程序里,在需要和终端交互的时候实现交互?

代码:

/*************server.c*****************/
setenv("QUERY_STRING", cgiargs, 1);
Dup2(fd, STDOUT_FILENO);         //把标准输出的句柄复制到文件句柄
Execve(filename, emptylist, environ); /* Run CGI program */

Execve里面执行的程序就是lsz,用于向串口传输文件。

问题解决:

cgi程序里面,主要做法:把不需要传回给sockfd的输出返回给终端就行了,那么就不会写到客户端的sockfd里面了。那么怎么实现呢?可以这样:因为在这个时候sockfd==STDOUT_FILENO,只需要把STDOUT_FILENO先保存下来oldsockfd,然后用open重新打开终端,然后用dup2把返回的描述符和STDOUT_FILENO联系在一起,这个时候输出又重定向到STDOUT_FILENO去了,然后输出结束,再用dup2把oldsockfd又和STDOUT_FILENO联系在一起。这时候输出又重定向到sockfd去了,下面是代码:

int oldsockfd = STDOUT_FILENO;
int ttyfd = open("/dev/tty",O_RDWR);
dup2(ttyfd,STDOUT_FILENO);
//do somethings
dup2(STDOUT_FILENO,oldsockfd);