cgi下不能使用popen問題的解決

用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,所以文件內部部分特殊字符因爲格式不一致,出現亂碼,造成此原因.

2.JAVASCRIPT輸出HTML字符時,前後標記不匹配.
    這種比較常見,往往在輸出字符串時,出現單引號(’)或雙引號(”)不配對,或者是在document.write()的時候,沒有正確輸出單引號(’)或雙引號(”)

3.參數內出現HTML標記語言或包含換行符
    我今天所遇到的是這種情況.因爲我所得到的數據以參數形式傳給一函數,結果該數據裏包含換行符,造成了此錯誤.如:一般測試時只使用單行的數據,是正常的,未出現這個錯誤,.當測試時使用多行數據,並使用回車鏈換行,就出行了此錯誤.因爲裏面包含了換行符
關於未結束的字符串常量看:http://yangfei520.blog.51cto.com/1041581/348278

這一下提醒了我 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程序運行的目錄裏 ,不然會出錯。

發佈了23 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章