技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 其他 --> 在CGI中执行外部命令的方法

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

浏览:1664次  出处信息

这几天在做的一个系统中,需要给指定的用户发送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,就这样吧~

QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1