天嵌 ARM开发社区

 找回密码
 注册
查看: 1732|回复: 4

cgi程序一点小问题 getcgidata函数

[复制链接]
yidehui 发表于 2013-8-27 13:41:16 | 显示全部楼层 |阅读模式
本帖最后由 yidehui 于 2013-8-27 15:27 编辑

我的实验目标:

建立一个静态的页面,上面有两个文本框,要求你输入用户名和密码,还有一个提交和重置的按钮,用于提交用户的输入,当用户点击提交按钮时,这个请求就被发送到服务器端,服务器上的CGI程序就会解析用户的输入,并且验证用户的输入是否合法,是否被通过验证等。


我已经移植了在jz2440上移植了BOA,输入网页代码建立user_password.html文件:(能够成功显示在IE上,说明网页文件搞定了)
<html>
<head><title>用户登陆验证</title></head>
<body>
<form name="form1" action="/cgi-bin/web_test.cgi" method="POST">
<table align="center">
    <tr><td align="center" colspan="2"></td></tr>
    <tr>
       <td align="right">用户名</td>
       <td><input type="text" name="Username"></td>
    </tr>
    <tr>
       <td align="right">密  码</td>
       <td><input type="password" name="Password"></td>
    </tr>
    <tr>
       <td><input type="submit" value="登  录"></td>
       <td><input type="reset" value="取  消"></td>
    </tr>
</table>
</form>
</body>
</html>



编译arm-linux-gcc web_test.c -o web_test.cgi
将web_test.cgi 放到2440根目录下的 /var/www/cgi-bin/

CGI处理程序的源码(web_test.c 文件,):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* getcgidata(FILE* fp, char* requestmethod);
int main()
{
       char *input;
       char *req_method;
       char name[64];
       char pass[64];
       int i = 0;
       int j = 0;
      
//     printf("Content-type: text/plain; charset=iso-8859-1\n\n");
       printf("Content-type: text/html\n\n");
       printf("The following is query reuslt:<br><br>");

       req_method = getenv("REQUEST_METHOD");
       input = getcgidata(stdin, req_method);

       // 我们获取的input字符串可能像如下的形式
       // Username="admin"&Password="aaaaa"
       // 其中"Username="和"&Password="都是固定的
       // 而"admin"和"aaaaa"都是变化的,也是我们要获取的
      
       // 前面9个字符是UserName=
       // 在"UserName="和"&"之间的是我们要取出来的用户名
       for ( i = 9; i < (int)strlen(input); i++ )
       {
              if ( input == '&' )
              {
                     name[j] = '\0';
                     break;
              }                  
              name[j++] = input;
       }

       // 前面9个字符 + "&Password="10个字符 + Username的字符数
       // 是我们不要的,故省略掉,不拷贝
       for ( i = 19 + strlen(name), j = 0; i < (int)strlen(input); i++ )
       {
              pass[j++] = input;
       }
       pass[j] = '\0';

       printf("Your Username is %s<br>Your Password is %s<br> \n", name, pass);
      
       return 0;
}

char* getcgidata(FILE* fp, char* requestmethod)
{
       char* input;
       int len;
       int size = 1024;
       int i = 0;
      
       if (!strcmp(requestmethod, "GET"))
       {
              input = getenv("QUERY_STRING");
              return input;
       }
       else if (!strcmp(requestmethod, "POST"))
       {
              len = atoi(getenv("CONTENT_LENGTH"));
              input = (char*)malloc(sizeof(char)*(size + 1));
            
              if (len == 0)
              {
                     input[0] = '\0';
                     return input;
              }
            
              while(1)
              {
                     input = (char)fgetc(fp);
                     if (i == size)
                     {
                            input[i+1] = '\0';
                            return input;
                     }
                    
                     --len;
                     if (feof(fp) || (!(len)))
                     {
                            i++;
                            input = '\0';
                            return input;
                     }
                     i++;
                    
              }
       }
       return NULL;
}

上述的程序是我从网上参考下来的,运行上述的cgi程序(在运行了./boa和http://192.168.0.200/user_password.html基础之上)时,出现Segmentation fault。我用注释的方法确定范围,发现是getcgidata函数。如果注释了这个函数,则运行不会出现Segmentation fault。曾经尝试着把getcgidata函数内部所有内容注释掉,只是return NULL而已,也有错误!!!这是什么问题啊!
yuki 发表于 2013-8-27 14:56:34 | 显示全部楼层
Segmentation fault就是linux臭名远播的段错误。一般是使用了指向不存在的内存地址。一般情况下空指针经常出现这类错误。
从代码初步推断应该是以下这2句出了问题:
req_method = getenv("REQUEST_METHOD");
input = getcgidata(stdin, req_method);

第一句应该没获奖到值,那就是空指针。
接着下面那句getcgidata函数参数为空指针,就报错了。
所以一般指针使用前都要判断是否为空。


 楼主| yidehui 发表于 2013-8-27 15:54:56 | 显示全部楼层
yuki 发表于 2013-8-27 14:56
Segmentation fault就是linux臭名远播的段错误。一般是使用了指向不存在的内存地址。一般情况下空指针经常出 ...

我测试了确实是返回NULL ,但网上的程序都是获取环境变量:getenv("REQUEST_METHOD");
 楼主| yidehui 发表于 2013-8-27 16:59:14 | 显示全部楼层
本帖最后由 yidehui 于 2013-8-27 20:36 编辑

已经解决了
yuki 发表于 2013-8-27 23:56:28 | 显示全部楼层
yidehui 发表于 2013-8-27 16:59
已经解决了

把解决的方法写一下。谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-19 15:33 , Processed in 1.062500 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表