用C进行Cgi编程,从我的cgi程序中调用system()。

时间:2018-12-27 04:08:07

标签: c cgi system

我有一个用C语言编写的CGI程序,已经使用了20多年,而且很长一段时间以来,我第一次在Windows中运行,特别是Windows 10,但是我无法从CGI程序执行的system()调用。似乎只是忽略了系统调用,并没有在我期望的服务器端创建我的输出。
从表单调用CGI程序,并使用sprintf将html页面响应组成一个巨大的缓冲区(szbuffer),然后打印到stdout,后者在apache世界中返回给客户端。这是将构建的html页面输出给用户的例程:

    /** Print the CGI response header, required for all HTML output. **/
    /** Note the extra \n, to send the blank line.                  **/
    printf("Content-type: text/html\n\n") ;

    printf("%s\n<!--JL 7/12/01 11:00am -->\n",szBuffer); 
    free ( szBuffer); 

现在这已经可以工作好多年了,但是在这个版本中,我想运行一些系统调用来搜索csv文件并创建一个答案集,以便使用fopen()进行读取。我在linux中完成此操作的方法是仅使用system()命令运行命令:

         getvaluecgivar(szcustomer_chain, "cust_field3", globals); 
         getvaluecgivar(szcustomer_id, "cust_field4", globals); 

         //sprintf(szdoscommand,"./awklookup_customer_id.bat %s %s "
         sprintf(szdoscommand,"awklookup_customer_id.bat %s %s"
    ,szcustomer_chain
    ,szcustomer_id
    ); 

          system(szdoscommand);
          system("cat lunch.trace >hw.lis");
          system("cat lunch.trace >/temp/hwt.lis");

          sprintf(szTempstring,"system command:%s: return code=%d\n"
      ,szdoscommand
      ,return_from_system_call
              );
        strcat(szBuffer, szTempstring); 

         } // then lookup by customer id

出于我需要解释和解决的原因,似乎好像system()调用(它们全部三个)从未执行。这两个“ cat Lunch.trace”系统调用只是一个测试,以查看是否可以运行任何系统调用,并且这些命令似乎也失败了。现在,我知道我已经在Linux上完成了此操作,之前没有任何问题:

        FILE * tfile;

        system( "cat /tmp/relaystatus20*.txt >/tmp/rs20all.txt"); 

        tfile = fopen( "/tmp/rs20all.txt" , "r");
        if (tfile) {
            strcat(szBuffer, "<pre>"); 
                while(!feof(tfile)) {

,这将在/ tmp目录中创建文件rs20all.txt。

在Windows上我需要做些特别的事情吗?我确实从awklookup_customer_id.bat中捕获了返回代码,它是127。

这是awklookup_customer_id.bat,它可以从dos提示符cmd.exe或cygwin64终端正常运行:

  call \jon\bat\local >t.lis
  rem echo %1%, %2%
  set arg1=%1%
  set arg2=%2%

  gawk -F',' '{ if($3==%arg1%)  print $0 }' t5_clean_customer.csv >awk01.lis
  gawk -F',' '{ if($4==%arg2%)  print $0 }' awk01.lis >awk02.lis
  \jon\bat\grep.exe -nf awk02.lis t5_clean_customer.csv >awk03.lis
  cat awk03.lis|wc -l >awk03_c.lis
  set LINE_COUNT=0
  set /p LINE_COUNT=<awk03_c.lis
  cut -d: -f1 awk03.lis >awk03_ln.lis
  set LINE_NUMBER=0
  set /p LINE_NUMBER=<awk03_ln.lis
  SET /A Result = %LINE_COUNT% * 10000000 + %LINE_NUMBER%
  echo number of lines that match :%LINE_COUNT% line number: %LINE_NUMBER%
  rem pause
  exit  %Result%

我正在运行Apache 2.4,这是cgi程序获取的环境变量:

  Print_environ::
  [HTTP_HOST=localhost]
  [HTTP_CONNECTION=keep-alive]
  [CONTENT_LENGTH=380]
  [HTTP_CACHE_CONTROL=max-age=0]
  [HTTP_ORIGIN=http://localhost]
  [HTTP_UPGRADE_INSECURE_REQUESTS=1]
  [CONTENT_TYPE=application/x-www-form-urlencoded]
  [HTTP_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36]
  [HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8]
  [HTTP_REFERER=http://localhost/cgi-bin/bf_customer.cgi]
  [HTTP_ACCEPT_ENCODING=gzip, deflate, br]
  [HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.9]
  [PATH=/cygdrive/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/cygdrive/c/Program Files (x86)/Intel/iCLS Client:/cygdrive/c/Program Files/Intel/iCLS Client:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files (x86)/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/cygdrive/c/Windows/system32/config/systemprofile/.dnx/bin:/cygdrive/c/Program Files/Microsoft DNX/Dnvm:/cygdrive/c/Program Files (x86)/Windows Kits/8.1/Windows Performance Toolkit:/cygdrive/c/Program Files/Intel/WiFi/bin:/cygdrive/c/Program Files/Common Files/Intel/WirelessCommon:/cygdrive/c/Program Files (x86)/2Printer:/cygdrive/c/Program Files/MATLAB/MATLAB Runtime/v93/runtime/win64:/cygdrive/c/Program Files (x86)/Pico Technology/PicoScope6:/cygdrive/c/Program Files (x86)/IVI Foundation/VISA/WinNT/Bin:/cygdrive/c/Program Files/IVI Foundation/VISA/Win64/Bin:/cygdrive/c/Users/jleslie/AppData/Local/Microsoft/WindowsApps]
  [SYSTEMROOT=C:\Windows]
  [COMSPEC=C:\Windows\system32\cmd.exe]
  [PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC]
  [WINDIR=C:\Windows]
  [SERVER_SIGNATURE=]
  [SERVER_SOFTWARE=Apache/2.4.23 (Win64)]
  [SERVER_NAME=localhost]
  [SERVER_ADDR=::1]
  [SERVER_PORT=80]
  [REMOTE_ADDR=::1]
  [DOCUMENT_ROOT=C:/jon/programs/Apache24/htdocs]
  [REQUEST_SCHEME=http]
  [CONTEXT_PREFIX=/cgi-bin/]
  [CONTEXT_DOCUMENT_ROOT=c:/jon/programs/Apache24/cgi-bin/]
  [SERVER_ADMIN=admin@example.com]
  [SCRIPT_FILENAME=C:/jon/programs/Apache24/cgi-bin/bf_customer.cgi]
  [REMOTE_PORT=52945]
  [GATEWAY_INTERFACE=CGI/1.1]
  [SERVER_PROTOCOL=HTTP/1.1]
  [REQUEST_METHOD=POST]
  [QUERY_STRING=]
  [REQUEST_URI=/cgi-bin/bf_customer.cgi]
  [SCRIPT_NAME=/cgi-bin/bf_customer.cgi]
  [TERM=cygwin]
  [HOME=/home/jleslie]
  cgi vars:
  [colora] = [maroon]
  [cust_field1] = []
  [cust_field2] = []
  [cust_field3] = [0]
  [cust_field4] = [16]

1 个答案:

答案 0 :(得分:0)

我知道了。答案与httpd.conf有关。我需要告诉apache可以运行.bat文件:

   # (You will also need to add "ExecCGI" to the "Options" directive.)
   #
   #AddHandler cgi-script .cgi
   AddHandler cgi-script .bat # add .exe if you wish
   Options +ExecCGI +FollowSymlinks

很抱歉与return_from_system_call混淆,我经常添加和删除它,所以我经常发布未设置代码的版本。这是有效的最终代码部分:

         getvaluecgivar(szcustomer_chain, "cust_field3", globals); 
         getvaluecgivar(szcustomer_id, "cust_field4", globals); 

         sprintf(szdoscommand,"awklookup_customer_id.bat %s %s"
                 ,szcustomer_chain
                 ,szcustomer_id
                 ); 

          return_from_system_call =system(szdoscommand);

          sprintf(szTempstring,"system command:%s: return code=%d\n"
                  ,szdoscommand
                  ,return_from_system_call
                  );
          strcat(szBuffer, szTempstring);