onki
asked on
atoi(getenv())
In my cgi program (written in C) for the guestbook of my homepage, several lines of codes are listed below:
:
printf("Content-type: text/html%c%c",10,10);
len=atoi(getenv("CONTENT_L ENGTH"));
for(i=0; len && (!feof(stdin)); i++) {
m=i;
inputs[i].val=ReadStdin(st din,'&',&l en);
AddToSpace(inputs[i].val);
Convert(inputs[i].val);
inputs[i].name=ReadData(in puts[i].va l,'=');
} :
When I try to run it, segmentation fault exists. I notice that it is the problem of the line:
len=atoi(getenv("CONTENT_L ENGTH"));
but I don't know how to correct it. Can anyone help?
:
printf("Content-type: text/html%c%c",10,10);
len=atoi(getenv("CONTENT_L
for(i=0; len && (!feof(stdin)); i++) {
m=i;
inputs[i].val=ReadStdin(st
AddToSpace(inputs[i].val);
Convert(inputs[i].val);
inputs[i].name=ReadData(in
} :
When I try to run it, segmentation fault exists. I notice that it is the problem of the line:
len=atoi(getenv("CONTENT_L
but I don't know how to correct it. Can anyone help?
ASKER
How to set the CONTENT_LENGTH?
p.s. your code doesn't work.
p.s. your code doesn't work.
You problem is that CONTENT_LENGTH isn't present and thus getenv returns NULL which is invalid as an arguement to atoi.
The reason that CONTENT_LENGTH is missing is because I would imagine the CGI was called via a GET which when used places the name value pairs in QUERY_STRING rather than via stdin and does not set the CONTENT_LENGTH.
To determine whether POST or GET was used you should check the environment variable REQUEST_METHOD.
rbrs code is correct except for the typo in the definition of env although I would use a different variable name as some compilers supply a function called env().
Steve
The reason that CONTENT_LENGTH is missing is because I would imagine the CGI was called via a GET which when used places the name value pairs in QUERY_STRING rather than via stdin and does not set the CONTENT_LENGTH.
To determine whether POST or GET was used you should check the environment variable REQUEST_METHOD.
rbrs code is correct except for the typo in the definition of env although I would use a different variable name as some compilers supply a function called env().
Steve
ASKER
For my cgi program, I used
<FORM METHOD="POST" ACTION="/cgi-bin/guestmsg. cgi">
but not "GET" as you said.
<FORM METHOD="POST" ACTION="/cgi-bin/guestmsg.
but not "GET" as you said.
According to the HTTP spec there are circumstances where browsers are known to wrongly change POSTS to GETS. Whilst you haven't said anything that implies that this is the case here it may be just as well to trap GET as well.
That aside can you post the rest of the code as it would seem that the problem is elsewhere. In particular I would be interested to see the variable definition.
In addition what Web Server is involved and what platform?
That aside can you post the rest of the code as it would seem that the problem is elsewhere. In particular I would be interested to see the variable definition.
In addition what Web Server is involved and what platform?
interesting...
ASKER
/* below are the codes of my cgi program */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct {
char *name;
char *val;
}input;
char *ReadStdin(FILE *f, char stop, int *len);
void AddToSpace(char *str);
void Convert(char *url);
char *ReadData(char *line, char stop);
main(int argc, char *argv[])
{
char *env;
input inputs[10000];
register int i, m=0;
int len;
time_t Ourtime;
FILE *fp, *fopen();
fp=fopen("/Guest/guestbook .htm","a") ;
printf("Content-type: text/html%c%c",10,10);
*env=getenv("CONTENT_LENGT H");
if(*env) len=atoi(env);
else {
len=0;
fprintf(stderr,"CONTENT_LE NGTH not found\n");
}
for(i=0; len && (!feof(stdin)); i++) {
m=i;
inputs[i].val=ReadStdin(st din,'&',&l en);
AddToSpace(inputs[i].val);
Convert(inputs[i].val);
inputs[i].name=ReadData(in puts[i].va l,'=');
}
printf("<H1>Thank you for you opinion, %s! </H1>", inputs[0].val);
printf("<H3>your e-mail is %s! </H3>", inputs[1].val);
printf("<H3>your opinion is %s! </H3>", inputs[2].val);
fputs("\n<p>name: ", fp);
fputs(inputs[0].val,fp);
fputs(",email: ", fp);
fputs(inputs[1].val, fp);
fputs(", opinion:", fp);
fputs(inputs[2].val, fp);
fclose(fp);
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct {
char *name;
char *val;
}input;
char *ReadStdin(FILE *f, char stop, int *len);
void AddToSpace(char *str);
void Convert(char *url);
char *ReadData(char *line, char stop);
main(int argc, char *argv[])
{
char *env;
input inputs[10000];
register int i, m=0;
int len;
time_t Ourtime;
FILE *fp, *fopen();
fp=fopen("/Guest/guestbook
printf("Content-type: text/html%c%c",10,10);
*env=getenv("CONTENT_LENGT
if(*env) len=atoi(env);
else {
len=0;
fprintf(stderr,"CONTENT_LE
}
for(i=0; len && (!feof(stdin)); i++) {
m=i;
inputs[i].val=ReadStdin(st
AddToSpace(inputs[i].val);
Convert(inputs[i].val);
inputs[i].name=ReadData(in
}
printf("<H1>Thank you for you opinion, %s! </H1>", inputs[0].val);
printf("<H3>your e-mail is %s! </H3>", inputs[1].val);
printf("<H3>your opinion is %s! </H3>", inputs[2].val);
fputs("\n<p>name: ", fp);
fputs(inputs[0].val,fp);
fputs(",email: ", fp);
fputs(inputs[1].val, fp);
fputs(", opinion:", fp);
fputs(inputs[2].val, fp);
fclose(fp);
}
Take a look at this URL:
http://www.icorp.net/wdg/
This lists a complete C-based guestbook (with source) that I wrote for the book, "HTML & CGI Unleashed" which uses the NCSA library code which is also on the site. The actual link to test-run the script is outdated but the code definitely works.
http://www.icorp.net/wdg/
This lists a complete C-based guestbook (with source) that I wrote for the book, "HTML & CGI Unleashed" which uses the NCSA library code which is also on the site. The actual link to test-run the script is outdated but the code definitely works.
Youe problem is here
*env=getenv("CONTENT_LENGT H");
if(*env) len=atoi(env);
this should read
env=getenv("CONTENT_LENGTH ");
if(env) len=atoi(env);
Steve
*env=getenv("CONTENT_LENGT
if(*env) len=atoi(env);
this should read
env=getenv("CONTENT_LENGTH
if(env) len=atoi(env);
Steve
that's right...how could that slip by me...damn pointers :-)
ASKER
Segmentation fault is not caused by those two lines of code. Segmentation fault exists after the if-then condition.
Can you post the code of ReadStdin pls.
Yes because you have stored the returned value from getenv at the address contained in env which at this point in time is unitialised. The chances are that it has stored the value at some abstract taken from the stack or 0.
When you the subsequently access env to obtain its length the function will search through the 'string' until it finds a null character. But as the string is not being addressed it will plough on until it happens upon a null or it generates a segment fault.
If you are really unlucky the actual problem may not even manifest itself within an access to env as the action of storing a value at an arbitary address can damage other structures within a program (I don't mean C structures here) such as the stack which can cause returns to the wrong place.
Try my solution and see if the problem disappears or at least changes. Whilst I can't be certain that there aren't some other problems with you program I would be willing to gamble more than you could afford that the two lines I mentioned are wrong.
Steve
When you the subsequently access env to obtain its length the function will search through the 'string' until it finds a null character. But as the string is not being addressed it will plough on until it happens upon a null or it generates a segment fault.
If you are really unlucky the actual problem may not even manifest itself within an access to env as the action of storing a value at an arbitary address can damage other structures within a program (I don't mean C structures here) such as the stack which can cause returns to the wrong place.
Try my solution and see if the problem disappears or at least changes. Whilst I can't be certain that there aren't some other problems with you program I would be willing to gamble more than you could afford that the two lines I mentioned are wrong.
Steve
ASKER
I have tried your answer. However, segmentation fault still exists after printing the warning
"CONTENT_LENGHT does not find"
I know that the CONTENT_LENGTH is NULL and so the warning is printed out. But my question is how to set the CONTENT_LENGTH correctly so that it is not NULL any more. (Since I input something to the form, the CONTENT_LEHGTH should not be NULL.)
"CONTENT_LENGHT does not find"
I know that the CONTENT_LENGTH is NULL and so the warning is printed out. But my question is how to set the CONTENT_LENGTH correctly so that it is not NULL any more. (Since I input something to the form, the CONTENT_LEHGTH should not be NULL.)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Actually, the segmentation fault still exists on the line
for((i=0; len && (!feof(stdin)); i++)
after I have tried your answer, since the value of len is NULL.
Anyway, I don't want to argue with you anymore on whether my original question is the question I asked. I give the marks to you now.
for((i=0; len && (!feof(stdin)); i++)
after I have tried your answer, since the value of len is NULL.
Anyway, I don't want to argue with you anymore on whether my original question is the question I asked. I give the marks to you now.
char *emv;
env=getenv("CONTENT_LENGTH
if (env) {
len=atoi(env);
} else {
len=0;
fprintf(stderr;"CONTENT_LE
}
Are you sure that CONTENT_LENGTH is set correctly?