0

This while loop is in server program and read call is linked to client via connfd which passes buff as name of file taken fom user via gets and passed through write call. if i paste "filename.txt" in fopen 1st argument it works but this buff as an argument causes fopen to report error as "No such file or directory". :( any help appriciated

while(read(connfd, buff, sizeof(buff))){
            write(1, buff, sizeof(buff));
            if((fp = fopen(buff, "r")) == NULL){
                perror("File Open error");
                write(connfd, "File Open error! File not found", sizeof("File Open error! File not found"));
            }else{
                send_file(fp, connfd);
                printf("\nFile sent Successfully! in server_helper");
            }
            bzero(buff, sizeof(buff));
        }
ali ahmed
  • 11
  • 4
  • What is the actual content of `buff` when you call `fopen`? That seems to be one of the first debugging steps. – William Pursell Jun 14 '21 at 22:26
  • 1
    Do you nul-terminate `buff`? It's hard to tell from the code snippet you have posted, Also, you should loop calling `read` until you have read all the bytes you're expecting. It's not guaranteed that you will get them all in one hit. – Paul Sanders Jun 14 '21 at 22:27
  • It would greatly help if you used the standard error message and just wrote, `perror(buff)`, but in this case there's a good chance that `buff` is missing the null-terminator, so that error message would be undefined behavior. But....if that is indeed the problem then your program already exhibited undefined behavior when you called `fopen`. – William Pursell Jun 14 '21 at 22:28
  • 2
    You don't check the return for `read` to determine how many characters were read (which can be less than `sizeof(buff)`), but then you blindly `write()` out `sizeof(buff)` chars. Better do basic I/O validation - otherwise you invite *Undefined Behavior*. – David C. Rankin Jun 14 '21 at 22:32
  • 1
    Please don't use `gets`. It's very dangerous. See https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used – Andy Lester Jun 14 '21 at 22:35
  • 1
    Surely `perror()` is reporting that error, not `fopen`? – Clifford Jun 14 '21 at 22:35

2 Answers2

0
read(connfd, buff, sizeof(buff))

Let's assume that read returns a positive value and buff is a static char array (char buff[N]), then you have a char array filled with some data but not a null-terminated string. In order to pass buff to fopen you have to append a '\0' at the end of the data in the buffer buff.

For that you need the result of read

ssize_t bytes_read = read(connfd, buff, sizeof(buff) - 1); //1 byte for '\0'
buff[bytes_read] = '\0'; //if bytes_read >= 0

After that, if you need the length of the string/data then you have to use strlen(buff). Since there could be fewer characters in the buffer than the buffers size (sizeof(buff) != strlen(buff)).

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11
  • I got it Thanks @Erdal Küçük i used strlen as sizeof gives full buff and i needed only the portion having data not all of it – ali ahmed Jun 15 '21 at 05:56
  • @aliahmed As you need to use the result from `read` to terminate your string, why not just use that value instead of calling `strlen`? – Gerhardh Jun 15 '21 at 07:09
0

I got it Thanks @Erdal Küçük i used strlen as sizeof gives full buff and i needed only the portion having data not all of it

while(read(connfd, buff, sizeof(buff) - 1)){   
            int len = strlen(buff);
            printf("%d",len);
            buff[strlen(buff) - 1] = '\0';
            write(1, buff, sizeof(buff));
            if((fp = fopen(buff, "r")) == NULL){
                perror("File Open error");
                write(connfd, "File Open error! File not found", sizeof("File Open error! File not found"));
            }else{
                send_file(fp, connfd);
                printf("\nFile sent Successfully! in server_helper");
            }
            bzero(buff, sizeof(buff));
        }
ali ahmed
  • 11
  • 4
  • I doubt that this works. The function `read` reads bytes into a buffer (`buf`). You can make this buffer to a 'null-terminated' string, by appending the '\0' character to the end of the valid data (result of `read`). You cannot use `strlen` on a non null-terminated string, since `strlen` counts the number of characters until '\0' is found. – Erdal Küçük Jun 15 '21 at 18:45
  • Actually i passed "ali.txt" as file name from client to server which is read by read call and when i checked lelngth of buff it was 8 but it should be 7 ("ali.txt") so i just made last character null-terminator by appending '\0' which worked as now fopen is opening all files which ever name i pass if it exits there. – ali ahmed Jun 15 '21 at 18:59