用C语言写的cgi程序,有个功能是返回软件版本号 ,由于软件版本号不是从文件中读取的,而是在linux上使用命令: /usr/local/bin/cmsserver//MonitorServer -v显示出来的。
所以用了popen()函数。当然我们也可以用system()函数,将上述命令的输出重定向到一个文件里然后再读取,但是这样做就要用到磁盘读取,老大不希望这样。
在用popen()函数取得命令的输出,要将输出传到web前端的input text类型编辑框内,问题出现了,popen函数返回正确,但是从popen()函数得到的返回buffer传给前端一直失败。
后来发现网页提示的错误信息是“未结束的字符串常量” ,才发现了原因。在网上查到出现这个错误的原因有3种:
1.JAVASCRIPT引用时,使用的字符语言不一致.
比如:<script type=”text/javascript” src=”xxx.js” charset=”UTF-8″>.xxx.js文件内部使用的是GB2312的格式,外面调用使用的是UTF-8,所以文件内部部分特殊字符因为格式不一致,出现乱码,造成此原因.
比如:<script type=”text/javascript” src=”xxx.js” charset=”UTF-8″>.xxx.js文件内部使用的是GB2312的格式,外面调用使用的是UTF-8,所以文件内部部分特殊字符因为格式不一致,出现乱码,造成此原因.
2.JAVASCRIPT输出HTML字符时,前后标记不匹配.
这种比较常见,往往在输出字符串时,出现单引号(’)或双引号(”)不配对,或者是在document.write()的时候,没有正确输出单引号(’)或双引号(”)
3.参数内出现HTML标记语言或包含换行符
我今天所遇到的是这种情况.因为我所得到的数据以参数形式传给一函数,结果该数据里包含换行符,造成了此错误.如:一般测试时只使用单行的数据,是正常的,未出现这个错误,.当测试时使用多行数据,并使用回车链换行,就出行了此错误.因为里面包含了换行符
这一下提醒了我 popen()的输出不正是有 换行符在里面吗?! ,所以把popen()的输出buffer里的换行符干掉就行了,尝试以后果然成功了,差不多纠结了今天一天,终于搞定。
下面是我cgi程序这部分的一段源码:
其中
buffer[ret-1]=0 就是为了干掉字符串结尾的换行符。
static int query_dev_info()
{
int ret = 0;
char sfver[64] = {0};
char* hwver = malloc(sizeof(char)*64);
char* typetext = malloc(sizeof(char)*64);
char text[1024] = {0};
char buffer[128]={0};
int i=0;
/*读取设备信息*/
memset(hwver,0,64);
FILE* fp = fopen("/etc/hwinfo","r");
if(fp)
{
char *p = 0,*q = 0;
memset(text,0x00,1024);
fread(text,1,1024,fp);
p = strcasestr(text,"Description:");
if(p)
{
q = strstr(p,"\n");
p += strlen("Description:");
strncpy(typetext,p,q-p );
while(typetext[0]==' ')
typetext++;
}
p = strcasestr(text,"HardwareVersion:");
if(p)
{
q = strstr(p,"\n");
p += strlen("HardwareVersion:");
strncpy(hwver,p,q-p );
while(hwver[0]==' ')
hwver++;
}
fclose(fp);
}
fp= popen("/usr/local/bin/cmsserver/MonitorServer -v", "r" );
if(fp )
{
ret = fread( buffer,1,128, fp );
buffer[ret-1]=0;
}
for(i=0;i<ret-1;i++)
{
if(buffer[i]==' ')
break;
}
strncpy(sfver,buffer,i);
htmlHeader("The temp page");
htmlBody();
fprintf(cgiOut,"<SCRIPT LANGUAGE=\"JavaScript\">");
fprintf(cgiOut,"parent.netconfigfrm.devtype.value='%s';\r\n",typetext);
fprintf(cgiOut,"parent.netconfigfrm.softver.value='%s';\r\n",sfver);
fprintf(cgiOut,"parent.netconfigfrm.hardwarever.value='%s';\r\n",hwver);
fprintf(cgiOut,"</SCRIPT>");
htmlFooter();
end:
ret = pclose(fp);
free(typetext);
free(hwver);
return ret;
}
最后还有一点就是 如果想我这种情况 MonitorServer的运行是需要动态库的 ,那么请把动态库copy一份到你cgi程序运行的目录里 ,不然会出错。