在CGI中执行外部命令的方法
这几天在做的一个系统中,需要给指定的用户发送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之前输出,所以报了这样的错误。
FILE *popen(const char *command, const char *type);
用popen("mailsend dantezhu"),命令内部的输出就会被重定向。
由于对于发送email这个命令本身我是不关心其成功与否的,所以并没有对其返回值做任何检查。
另外还有一点比较让人困惑,在apache下,我用CGI直接输出301跳转是会失败的,出错信息如下:
原来的输出方式是:
#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,就这样吧~
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Dante 来源: Vimer
- 标签: 在CGI 外部命令
- 发布时间:2010-06-05 11:42:48
- [71] Twitter/微博客的学习摘要
- [65] IOS安全–浅谈关于IOS加固的几种方法
- [64] find命令的一点注意事项
- [64] android 开发入门
- [62] Go Reflect 性能
- [62] 如何拿下简短的域名
- [60] Oracle MTS模式下 进程地址与会话信
- [60] 流程管理与用户研究
- [57] 图书馆的世界纪录
- [57] 读书笔记-壹百度:百度十年千倍的29条法则