IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

在CGI中执行外部命令的方法

Vimer 2010-06-05 11:42:48 累计浏览 2,294 次
本机暂存

这几天在做的一个系统中,需要给指定的用户发送email,由于对方只提供了可执行程序,所以需要在CGI中调用。

虽然之前就知道可以通过system()或者popen()来实现,但是在真正用在CGI场景中的时候还是吃了不少苦头。

先来看一下system(),函数声明如下:

int system(const char *command);

入参就是需要执行的命令,函数会返回成功或者失败。
这个函数有两个问题:
1.函数调用的时候会fork进程,对于有些webserver是禁止fork的。(我一开始在CGI调用全是返回-1,即fork失败)
2.命令执行时,如果有向标准输出打印,不会被重定向。即,在CGI中使用的杯具就是,会直接将打印信息返回给浏览器

对于第二条,假设我直接将输出重定向的结果会怎样呢,比如执行命令"ps -ef > x",实际上,在apache中执行的话,apache还是一样能拿到输出。由于我是在http header之前输出,所以报了这样的错误。

1
目前我的解决办法是用popen,函数声明如下:

FILE *popen(const char *command, const char *type);

用popen("mailsend dantezhu"),命令内部的输出就会被重定向。
由于对于发送email这个命令本身我是不关心其成功与否的,所以并没有对其返回值做任何检查。

另外还有一点比较让人困惑,在apache下,我用CGI直接输出301跳转是会失败的,出错信息如下:

2

原来的输出方式是:

#define MMANCGI_REDIRECT(ret)          
{                                                       
 char url[100];          
 if(ret)            
  snprintf(url,sizeof(url),"http://mman.qq.com/mman_error.html?ret=%d",ret);        
 else            
  snprintf(url,sizeof(url),"http://mman.qq.com/mman_succ.html");      
printf("HTTP/1.1 301 Moved Permanently\r\n");       
printf("Connection: close\r\n");                    
printf("Content-Type: text/html\r\n");              
printf("Location: %s\r\n\r\n", url);          
 return ret;           
};

后来改成:

int Output(ret)
{
    char url[100];
    if(ret)
  snprintf(url,sizeof(url),"http://mman.qq.com/mman_error.html?ret=%d",ret);
    else
  snprintf(url,sizeof(url),"http://mman.qq.com/mman_succ.html");
    PrintHttpHeader();
    cout <<
    "<script type=\"text/javascript\">document.domain=\"mman.qq.com\";location=\"" <<  url   << "\";</script>";
    return ret;
};

就没有问题了,应该是apache对支持301跳转需要额外的模块,由于任务在身,所以也就没有时间深究了。

OK,就这样吧~

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. AWStats是一个基于Perl的WEB日志分析工具。 (累计阅读 7,174)
  2. 网关协议学习:CGI、FastCGI、WSGI (累计阅读 4,707)
  3. HTTP Server开发相关学习资料整理推介 (累计阅读 4,513)
  4. 在CGI中通过Etag和Cache-Control来控制流量,访问量及生效时间 (累计阅读 4,331)
  5. 一个小小的C 写的web server (累计阅读 3,759)
  6. fork 与 IO 流的缓冲模式 (累计阅读 3,575)
  7. 关于一个gzip压缩问题的定位解决 (累计阅读 3,033)
  8. 更有效的进行前后台联调-让同一域名上的不同cgi访问不同的ip (累计阅读 2,322)
  9. 【IPC通信】基于管道的popen和pclose函数 (累计阅读 1,326)