views:

114

answers:

4

I hope the question explained my problem. I would also be grateful if the workaround that "works" is explained.

The traditional way of reading a file (that i know of)

int fd;
char buffer[MAX];
while(read(fd,buffer,MAX)>0)
{
         buffer[MAX]='\0';
         write(sockfd,buffer,MAX);
         memset(buffer,NULL,MAX);
}

was causing an overflow. The workaround that somehow unexpectedly worked was

   while((read(fd,buffer,MAX)!=0)||(read(fd,buffer,MAX)!= -1))
   {
         buffer[MAX]='\0';
         write(sockfd,buffer,MAX);
         memset(buffer,NULL,MAX);

   }

^^ This code printed out the entire file, no skips as far as observable.

Things like

do
{
     int temp;
     temp=read(fd,buffer,MAX);
     if((temp == 0) || (temp == -1))
     {
              break;
     }
     buffer[MAX]='\0';
     write(sockfd,buffer,MAX);
     memset(buffer,NULL,MAX);
 }while(1);

also caused a stack overflow. Am i missing something really important here?

Thanks

+3  A: 

Why do you say that it's causing an overflow?

Do note that read() will not write a \0 in the end of the char array, so if you do something like printf("%s", buffer) it will likely fail because printf will be expecting a NUL terminated string. You may be wanting to read MAX-1 and set buffer[number_of_read_characters] = '\0' where *number_of_read_characters* is whatever read() returned, if positive.

Also note that when you declare char buffer[MAX], since in C indexing is zero-based, the highest buffer index is MAX-1, so when you're setting buffer[MAX]='\0' you're already out of your array bounds.

Miguel Ventura
Because I get this message in the command line*** stack smashing detected ***:
qwrty
Sorry for the double comment, but this is not because of a runaway printf statement. The printf in the last line of the function is printed onto the screen. It is the return address ,etc that is geting corrupted.
qwrty
then you have your answer : Miguel Ventura has explained it all : You're out of bounds with buffer[MAX]
Samuel_xL
Thanks dude . You were right (so were the other folks).
qwrty
A: 

Glancing at the code, I'd suggest that it's because the logic is different.

In the example that works, the read(fd,buffer,MAX) method is being executed twice.

Think of it like:

while (dosomething() != 0 || dosomething() != -1)
{
    // some work
}

This loop will be infinite if the dosomething() method is idempotent, however if the first time you run it within the while statement is different than the second, it will break.

That explains how the execution path differs, but I can't figure out why the first option overflows... I'll think about it and update. (or not - it seems it's been answered!)

Damovisa
+1  A: 

One problem:

buffer[MAX]='\0';

steps on stack, as the highest valid index for array of size MAX is MAX-1 (due to 0-based indexes).

-1 return value from read indicates an error, so the right thing to test read() > 0. Moreover, the normal return value from read is the number of bytes read, and read does not guarantee any 0-termination. you have to do someting along the lines of

while (bytesRead=read() > 0) {
    write(buffer, bytesRead);
...
Arkadiy
A: 

Try this:

int fd, readCharacter;
char buffer[MAX];
while( readCharacter = read(fd, buffer, MAX**-1**) > 0 )
{
    buffer[readCharacter] = '\0';
    // ...
}
Patrice Bernassola