/ Check-in [72256634]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:If the read() system call in unix returns fewer bytes than expected, retry it until it either returns zero or an error.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | retry-short-reads
Files: files | file ages | folders
SHA1: 72256634773f6cba0aabaa3c953cd5daefd50e67
User & Date: drh 2011-11-01 15:45:28
Context
2011-11-01
15:45
If the read() system call in unix returns fewer bytes than expected, retry it until it either returns zero or an error. Closed-Leaf check-in: 72256634 user: drh tags: retry-short-reads
00:52
Version 3.7.9 check-in: c7c6050e user: drh tags: trunk, release, version-3.7.9
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  2940   2940   ** See tickets #2741 and #2681.
  2941   2941   **
  2942   2942   ** To avoid stomping the errno value on a failed read the lastErrno value
  2943   2943   ** is set before returning.
  2944   2944   */
  2945   2945   static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
  2946   2946     int got;
         2947  +  int total = 0;
  2947   2948   #if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  2948   2949     i64 newOffset;
  2949   2950   #endif
  2950   2951     TIMER_START;
         2952  +  while( cnt>0 ){
  2951   2953   #if defined(USE_PREAD)
  2952         -  do{ got = osPread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
  2953         -  SimulateIOError( got = -1 );
         2954  +    do{ got = osPread(id->h, pBuf, cnt, offset); }while(got<0 && errno==EINTR);
         2955  +    SimulateIOError( got = -1 );
  2954   2956   #elif defined(USE_PREAD64)
  2955         -  do{ got = osPread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR);
  2956         -  SimulateIOError( got = -1 );
         2957  +    do{ got = osPread64(id->h, pBuf,cnt,offset); }while(got<0 && errno==EINTR);
         2958  +    SimulateIOError( got = -1 );
  2957   2959   #else
  2958         -  newOffset = lseek(id->h, offset, SEEK_SET);
  2959         -  SimulateIOError( newOffset-- );
  2960         -  if( newOffset!=offset ){
  2961         -    if( newOffset == -1 ){
  2962         -      ((unixFile*)id)->lastErrno = errno;
  2963         -    }else{
  2964         -      ((unixFile*)id)->lastErrno = 0;			
         2960  +    newOffset = lseek(id->h, offset, SEEK_SET);
         2961  +    SimulateIOError( newOffset-- );
         2962  +    if( newOffset!=offset ){
         2963  +      if( newOffset == -1 ){
         2964  +        ((unixFile*)id)->lastErrno = errno;
         2965  +      }else{
         2966  +        ((unixFile*)id)->lastErrno = 0;			
         2967  +      }
         2968  +      return -1;
  2965   2969       }
  2966         -    return -1;
         2970  +    do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
         2971  +#endif
         2972  +    if( got<=0 ) break;
         2973  +    total += got;
         2974  +    cnt -= got;
         2975  +    offset += got;
         2976  +    pBuf = (void*)(got + (char*)pBuf);
  2967   2977     }
  2968         -  do{ got = osRead(id->h, pBuf, cnt); }while( got<0 && errno==EINTR );
  2969         -#endif
  2970   2978     TIMER_END;
  2971   2979     if( got<0 ){
  2972   2980       ((unixFile*)id)->lastErrno = errno;
         2981  +    total = got;
  2973   2982     }
  2974         -  OSTRACE(("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
  2975         -  return got;
         2983  +  OSTRACE(("READ    %-3d %5d %7lld %llu\n", id->h,total,offset,TIMER_ELAPSED));
         2984  +  return total;
  2976   2985   }
  2977   2986   
  2978   2987   /*
  2979   2988   ** Read data from a file into a buffer.  Return SQLITE_OK if all
  2980   2989   ** bytes were read successfully and SQLITE_IOERR if anything goes
  2981   2990   ** wrong.
  2982   2991   */