Dobra, czas wam podać te funkcje bo nie będę was zmuszał do zgadywania co tam się dzieje, wszystkie są moje (własny kod), rzeczywiście tam powinno być ptr=sec_realloc(... Poprawiłem jednak nadal mam SEGV.
Dobra, no to owy main pierwszy:
int main()
{
int sockd, new_sockd; /* listen on sockd, new connection on new_sockd */
struct sockaddr_in my_addr; /* my address information */
struct sockaddr_in their_addr; /* client address information */
char *request; /* Pointer to the request string as sent by client */
char *temp_req; /* Temporary place to store the request template */
char *hostname; /* Hostname copeied out from a request */
int i;
socklen_t sin_size;
long long content_length;
long long point=0;
struct part *queue;
struct part *starting_point;
sockd=sec_socket(AF_INET, SOCK_STREAM, 0, err_notice, NULL);
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */
if(bind(sockd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1) {
perror("bind");
exit(1);
}
if(listen(sockd, BACKLOG)==-1) {
perror("listen");
exit(1);
}
sin_size=sizeof(their_addr);
while((new_sockd=accept(sockd,(struct sockaddr*)&their_addr, &sin_size))!=-1) {
if((request=recv_data(request, new_sockd, new_sockd))==NULL) {
close(new_sockd);
continue;
}
hostname=find_host(request, new_sockd);
content_length=query_length(request, hostname, new_sockd);
queue=sec_malloc(sizeof(struct part), err_notice, new_sockd, "Server out of memory", NULL);
starting_point=queue->prev=queue;
for(i=0;content_length>0;i++) {
queue->id=i;
if(content_length>=1500) {
queue->size=1500;
content_length-=1500;
queue->start=point;
point+=1500;
queue->end=point;
} else {
queue->size=content_length;
queue->start=point;
point+=content_length;
queue->end=point;
content_length=0;
}
temp_req=forge_template(request, queue->start, queue->end, new_sockd);
queue->req_temp=sec_malloc(strlen(temp_req)+1);
memmove(queue->req_temp, temp_req, strlen(temp_req)+1);
free(temp_req);
queue->next=sec_malloc(sizeof(struct part), err_notice, new_sockd, "Server out of memory", NULL);
queue->next->prev=queue;
queue=queue->next;
}
queue->prev->next=starting_point;
starting_point->prev=queue->prev;
free(queue);
queue=starting_point;
return 0;
}
Oto i on, mam tam wywołanie funkcji find_host która tak oto się prezentuje:
/* This function copies the hostname from the header and returns it back. */
char *find_host(char *request, int sockd)
{
char *ptr;
char *hostname;
int i;
ptr=strstr(request,"Host:")+5;
while(*ptr==' ')
ptr++;
hostname=sec_malloc(256, err_notice, sockd, "Server out of memory", NULL);
for(i=0;isalnum(*ptr)||*ptr=='.';i++,ptr++)
hostname[i]=*ptr;
hostname[i]='\0';
resize(hostname, 256, strlen(hostname)+1, sockd);
return hostname;
}
I na końcu tejże funkcji w linii XX robię resize() żeby nie tracić za dużo pamięci, tak oto się prezentuje resize():
/* This function is for enlarging block of allocated memory without
* changing the data that is stored in memory already. */
int resize(void *ptr, size_t size, size_t new_size, ...)
{
va_list ap;
char *temp;
int *check;
int sockd;
va_start(ap, new_size);
if((check=va_arg(ap, int *))!=NULL) {
sockd=(int)check;
va_end(ap);
temp=sec_malloc(size, err_notice, sockd, "Server out of memory", NULL);
memmove(temp, ptr, size);
ptr=sec_realloc(ptr, new_size, err_notice, sockd, "Server out of memory", NULL);
memmove(ptr, temp, size);
free(temp);
} else {
temp=sec_malloc(size, NULL);
memmove(temp, ptr, size);
ptr=sec_realloc(ptr, new_size, NULL);
memmove(ptr, temp, size);
free(temp);
}
return 0;
}
Wszystko przebiega ładnie i składnie dopóki nie dochodzę do free() - kiedy to dostaję SEGV.
Po drodze wykorzystuję dwie funkcje z mojej własnej kuchni, mianowicie sec_malloc i sec_realloc, które w tejże kolejności przytaczam poniżej:
void *sec_malloc(size_t size, ...)
{
va_list ap;
void *retval;
va_start(ap, size);
void (*notice_client)(va_list)=va_arg(ap, void *);
if((retval=malloc(size))==NULL) {
perror("malloc");
if(notice_client!=NULL)
notice_client(ap);
}
va_end(ap);
return retval;
}
void *sec_realloc(void *ptr, size_t size, ...)
{
va_list ap;
void *retval;
va_start(ap, size);
void (*notice_client)(va_list)=va_arg(ap, void *);
if((retval=realloc(ptr, size))==NULL) {
perror("realloc");
if(notice_client!=NULL)
notice_client(ap);
}
va_end(ap);
return retval;
}
Warto zaznaczyć że ani malloc ani realloc w tychże dwóch ostatnich funkcjach nie zwraca wskaźnika NULL więc i nie ma sensu rozpisywać się o tym co się dalej dzieje jeśli jest błąd bo to historia na kolejne kilka godzin.
Dość powiedzieć że dostaję SEGV, rzeczywiście ptr nie był ustawiany w należyty sposób lecz nawet po poprawieniu tegoż błędu nadal pozostaje koszmarny SEGV.
Proszę, pytajcie o co chcecie - sam to wszystko napisałem a program czy tak czy siak kiedy będzie gotowy będzie dostępny na licencji GPL.
Tutaj racja, jest to niewielkie prawdopodobieństwo że ptr kiedyś będzie zły i nadpisze ramke ale to jednak nie tym razem, gdb wyraźnie mówi:
(gdb) n
51 memmove(ptr, temp, size);
(gdb)
52 free(temp);
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0xb7ef2116 in malloc_set_state () from /lib/libc.so.6
(gdb) backtrace
#0 0xb7ef2116 in malloc_set_state () from /lib/libc.so.6
#1 0xb7ef230e in free () from /lib/libc.so.6
#2 0x0804933b in resize (ptr=0x804c180, size=256, new_size=21) at controller.h:52
#3 0x08049784 in find_host (request=0x804c050 "GET / HTTP/1.1\r\nHost: intranet.acision.com\r\n\r\n", sockd=8) at controller.h:140
#4 0x08049da8 in main () at controller.c:57
Oczywiście prawidelnie poprawiłem błąd zaraz po tym jak go wskazałeś - dziękuję :)
Co myślicie?