다시 한번.. 메모리 누수.. 찾기..
글쓴이: leolo / 작성시간: 목, 2003/06/05 - 12:07오후
계속해서 CGI를 실행하면 메모리가 누수됩니다..
원인을 모르겠습니다..
일반적으로 들어오는 query는 다음과 같은 형식입니다.
기본 형식 [name=value]
mode=server&name=kiminsik...
이걸 차곡차곡 메모리를 뒤로 늘려가면서 하나씩 할당합니다.
그러니까?
struct cgi_object *list가 처음 들어온 mode=server를 가리키는 것이
아니라. 마지막으로 들어온 name=value를 가리키게됩니다.
혹시, 웹서버의 문제가 아닌지 하는 생각도 듭니다.
웹서버는 thttp를 사용하고 있습니다.
컴파일러는 arm-uclibc-gcc를 사용하였고요..
한가지더.. 부탁드리면..
boa웹서버를 설정하는 방법 좀 알려주세요..
영어로 된 웹사이트 말고, 한글로 설정하는 방법 좀 적혀있는거 없나요..
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define TEST 1
struct cgi_object {
char *name;
char *value;
struct cgi_object *next;
};
static struct cgi_object *list=NULL;
/* function to remove url encoding */
int url_decode(char *dst, char *src, int len)
{
int a=0, b=0;
int c;
while (b<len)
{
if (src[b]=='+')
{
dst[a++]=' ';
b++;
}
else if (src[b]=='%')
{
if (sscanf(&src[b+1],"%2x",&c)>0)
dst[a++]=c;
b+=3;
}
else dst[a++]=src[b++];
}
dst[a++]=0;
return (a);
}
void cgi_free(struct cgi_object *ptr)
{
struct cgi_object *current = ptr;
struct cgi_object *next;
while(current != NULL){
next = current->next;
if(current->name) free(current->name);
if(current->value) free(current->value);
free(current);
current = next;
}
ptr = NULL;
}
/* destructive to the query string */
static int cgi_split_pairs(char *query)
{
char *start = NULL, *mid = NULL, *end = NULL;
struct cgi_object *new = NULL;
int count = 0;
start=query;
while (start!=NULL && *start!=0)
{
int len;
if ((end=strchr(start, '&'))==NULL)
end=start+strlen(start);
if ((mid=strchr(start, '='))==NULL)
mid=end;
if (mid > end) mid=end;
if (start == mid)
{
start=end+1;
continue;
}
new=(struct cgi_object *)malloc(sizeof(*new));
if(new==NULL)
exit(1);
len=mid-start;
new->name=(char *)malloc(len+1);
if(new->name==NULL)
exit(1);
url_decode(new->name, start, len);
if (end > mid)
{
mid++;
len=end-mid;
new->value=(char *)malloc(len+1);
url_decode(new->value, mid, len);
new->value[len]=0;
}else
new->value=NULL;
new->next=list;
list=new;
start=end;
if (*start=='&') start++;
count++;
}
return (count);
}
#if 0
char *cgi_find(char *what)
{
struct cgi_object *ptr;
ptr=list;
while (ptr!=NULL)
{
if (!strcasecmp(what, ptr->name))
return(ptr->value);
ptr=ptr->next;
}
return(NULL);
}
char *cgi_nfind(char *what, int which)
{
struct cgi_object *ptr;
int i=1;
ptr=list;
while (ptr!=NULL)
{
if (!strcasecmp(what, ptr->name))
{
if (i==which)
return(ptr->value);
i++;
}
ptr=ptr->next;
}
return(NULL);
}
#endif
/* count the number of arguments,
or number of arguments with a specific name */
int cgi_count(char *what)
{
struct cgi_object *ptr;
int count=0;
ptr=list;
while (ptr!=NULL)
{
if (what==NULL || !strcmp(what, ptr->name))
count++;
ptr=ptr->next;
}
return (count);
}
/* master processing function */
int cgi_process(void)
{
static int done=0;
char *method, *query;
int count=0;
if (done) return ( cgi_count(NULL) );
if ((method=getenv("REQUEST_METHOD"))==NULL)
return(0);
if (!strcasecmp(method, "GET"))
{
if ((query=getenv("QUERY_STRING"))==NULL)
return(0);
query=strdup(query);
count=cgi_split_pairs(query);
free(query);
}else
if (!strcasecmp(method, "POST"))
{
int len;
if ((query=getenv("CONTENT_LENGTH"))==NULL)
return(0);
if ((len=atoi(query))<=0) return(0);
query=(char *)malloc(len+1);
if(query==NULL)
exit(1);
read(fileno(stdin), query, len);
query[len+1]=0;
count=cgi_split_pairs(query);
free(query);
}else
{
fprintf(stderr, "Unknown REQUEST_METHOD of '%s'\n", method);
return(0);
}
done=1;
return ( count );
}
#ifdef TEST
int main()
{
int i;
struct cgi_object *ptr;
i = cgi_process();
printf("Content-type: text/html\n\n");
printf("<html><body>\n");
printf("Got %d pairs<br>\n",i);
if (i>0)
{
printf("<ol>\n");
ptr=list;
while (ptr!=NULL)
{
printf("<li> %s", ptr->name);
if (ptr->value!=NULL)
printf(" = '%s'", ptr->value);
printf("\n");
ptr=ptr->next;
}
printf("</ol>\n");
}
printf("</body></html>\n");
cgi_free(list);
exit(0);
}
#endif
Forums:


댓글 달기