Thread: c sendfile doesn't works the 2nd time

  1. #1
    Registered User
    Join Date
    May 2012
    Location
    Italy
    Posts
    53

    c sendfile doesn't works the 2nd time

    This is the part of the ftp cmd "LIST" :
    Code:
        if(recv(newsockd, buffer, 5, 0) < 0){
        	perror("Errore nella ricezione comando LIST");
        	onexit(newsockd, sockd, 0, 2);
        }
        other = strtok(buffer, "\n");
        if(strcmp(other, "LIST") == 0){
        	printf("Ricevuta richiesta LIST\n");
        } else onexit(newsockd, sockd, 0, 2);
    
    
        count = file_list("./", &files);
        if((fp_list = fopen("listfiles.txt", "w")) == NULL){
          perror("Impossibile aprire il file per la scrittura LIST");
          onexit(newsockd, sockd, 0, 2);
        }
        for(i=0; i < count; i++){
          if(strcmp(files[i], "DIR ..") == 0 || strcmp(files[i], "DIR .") == 0) continue;
          else{
            fprintf(fp_list, "%s\n", files[i]);
          }
        }
        fclose(fp_list);
        if((fpl = open("listfiles.txt", O_RDONLY)) < 0){
          perror("open file with open");
          onexit(newsockd, sockd, 0, 2);
          exit(1);
        }
        if(fstat(fpl, &fileStat) < 0){
          perror("Errore fstat");
          onexit(newsockd, sockd, fpl, 3);
        }
        fsize = fileStat.st_size;
        if(send(newsockd, &fsize, sizeof(fsize), 0) < 0){
          perror("Errore durante l'invio grande file list");
          onexit(newsockd, sockd, fpl, 3);
        }
        rc_list = sendfile(newsockd, fpl, &offset_list, fileStat.st_size);
        if(rc_list == -1){
          perror("Invio file list non riuscito");
          onexit(newsockd, sockd, fpl, 3);
        }
        if((uint32_t)rc_list != fsize){
          fprintf(stderr, "Trasferimento incompleto: %d di %d bytes inviati\n", rc_list, (int)fileStat.st_size);
          onexit(newsockd, sockd, fpl, 3);
        }
        close(fpl);
        if(remove( "listfiles.txt" ) == -1 ){
          perror("errore cancellazione file");
          onexit(newsockd, sockd, 0, 2);
        }
    		memset(buffer, 0, sizeof(buffer));
    this is the function file_list:
    Code:
    #include "prototypes.h"
    
    
    uint32_t file_list(char *path, char ***ls){
    	DIR *dp;
      struct stat fileStat;
      struct dirent *ep = NULL;
      uint32_t len, count = 0;
      int file = 0;
      *ls = NULL;
      dp = opendir (path);
      if(dp == NULL){
        fprintf(stderr, "Non esiste la directory: %s\n", path);
        exit(1);
      }
    
    
      ep = readdir(dp);
      while(NULL != ep){
        count++;
        ep = readdir(dp);
      }
      rewinddir(dp);
    
    
      *ls = calloc(count, sizeof(char *));
      count = 0;
      ep = readdir(dp);
      while(ep != NULL){
        if((file = open(ep->d_name, O_RDONLY)) < 0){
          perror("apertura file");
          exit(1);
        }
        if(fstat(file, &fileStat) != 0){
          perror("filestat");
          free(*ls);
          close(file);
          exit(EXIT_FAILURE);
        }
        close(file);
        if(S_ISDIR(fileStat.st_mode)){
          len = strlen(ep->d_name);
          (*ls)[count] = malloc(len+5); /* lunghezza stringa + "DIR \n" */
          strcpy((*ls)[count], "DIR "); /* copio DIR */
          strcat((*ls)[count++], ep->d_name); /* concateno la stringa DIR con il nome della dir */
          ep = readdir(dp);
        }
        else{
          (*ls)[count++] = strdup(ep->d_name);
          ep = readdir(dp);
        }
      }
      (void)closedir(dp);
      return count;
    }
    What is the problem?
    When i call the LIST cmd the 1st time it is all ok but when i call it the 2nd time the files is partially sent and i don't know why O.o

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Why do you think a short write is a fatal error? Why aren't you trying to resend the unsent portion?

  3. #3
    Registered User
    Join Date
    May 2012
    Location
    Italy
    Posts
    53
    With this it doesn't works

    Code:
    send_again:
        rc_list = sendfile(newsockd, fpl, &offset_list, fileStat.st_size);
        if(rc_list == -1){
          perror("Invio file list non riuscito");
          onexit(newsockd, sockd, fpl, 3);
        }
        if((uint32_t)rc_list != fsize){
          fprintf(stderr, "Trasferimento incompleto: %d di %d bytes inviati\n", rc_list, (int)fileStat.st_size);
          goto send_again;
          //onexit(newsockd, sockd, fpl, 3);
        }
    Last edited by polslinux; 08-08-2012 at 01:48 AM.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    If send() doesn't send all your data then you are not supposed to resend everything.
    You are supposed to keep sending until all your data is transmitted.
    Meaning after a part of your data was sent, send the data from the offset that send has returned.
    Kurt

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It should be something like this
    Code:
    do {
      n = send(sock,buff,remainder);
      if ( n > 0 ) {
        buff  += n;
        remainder -= n;
      } else
      if ( n == 0 ) {
        // remote disconnected
      } else {
        // some error
        // EAGAIN isn't fatal if the socket is non-blocking
      }
    } while ( remainder > 0 );
    It advances through the buffer until it has been consumed, or something went wrong.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Italy
    Posts
    53
    i've solved
    the problem was that i have to put offset_list = 0; BEFORE every call to sendfile

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why doesn't it works?
    By curious in forum C Programming
    Replies: 21
    Last Post: 05-24-2008, 06:04 PM
  2. Why This doesn't work and the other one works?
    By chottachatri in forum C++ Programming
    Replies: 21
    Last Post: 03-26-2008, 08:01 AM
  3. Why <complete program> doesn't works right?
    By Gamer_Jimbo in forum C++ Programming
    Replies: 3
    Last Post: 01-19-2006, 02:28 AM
  4. 'GetConsoleWindow' doesn't works ??!
    By andre123 in forum Windows Programming
    Replies: 11
    Last Post: 09-10-2003, 11:45 PM
  5. Works on Dev C++, Doesn't on Visual C++ :(
    By marcvb in forum C++ Programming
    Replies: 6
    Last Post: 11-26-2001, 08:39 AM