size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, myf MyFlags) { size_t readbytes; int error= 0; DBUG_ENTER("my_pread"); DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); for (;;) { errno= 0; /* Linux, Windows don't reset this on EOF/success */ #if defined(_WIN32) readbytes= my_win_pread(Filedes, Buffer, Count, offset); #else readbytes= pread(Filedes, Buffer, Count, offset); #endif error= (readbytes != Count); if(error) { my_errno= errno ? errno : -1; if (errno == 0 || (readbytes != (size_t) -1 && (MyFlags & (MY_NABP | MY_FNABP)))) my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d", (int) readbytes, (uint) Count,Filedes,my_errno)); if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR) { DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d", (int) readbytes)); continue; /* Interrupted */ } if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { char errbuf[MYSYS_STRERROR_SIZE]; if (readbytes == (size_t) -1) my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes), my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); else if (MyFlags & (MY_NABP | MY_FNABP)) my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes), my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP))) DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ } if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Read went ok; Return 0 */ DBUG_RETURN(readbytes); /* purecov: inspected */ } } /* my_pread */
size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, myf MyFlags) { size_t readbytes; size_t total_readbytes= 0; int error= 0; #if !defined (HAVE_PREAD) && !defined (_WIN32) int save_errno; #endif DBUG_ENTER("my_pread"); DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); for (;;) { errno= 0; /* Linux, Windows don't reset this on EOF/success */ #if !defined (HAVE_PREAD) && !defined (_WIN32) mysql_mutex_lock(&my_file_info[Filedes].mutex); readbytes= (uint) -1; error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 || (readbytes= read(Filedes, Buffer, Count)) != Count); save_errno= errno; mysql_mutex_unlock(&my_file_info[Filedes].mutex); if (error) errno= save_errno; #else #if defined(_WIN32) readbytes= my_win_pread(Filedes, Buffer, Count, offset); #else readbytes= pread(Filedes, Buffer, Count, offset); #endif error= (readbytes != Count); #endif if (readbytes > 0) total_readbytes+= readbytes; if(error) { if (readbytes > 0 && readbytes < Count && errno == 0) { /* pread() may return less bytes than requested even if enough bytes are available according to the Linux man page. This makes determining the end-of-file condition a bit harder. We just do another pread() call to see if more bytes can be read, since all my_pread() users expect it to always return all available bytes. For end-of-file 0 bytes is returned. This can never be the case for a partial read, since according to the man page, -1 is returned with errno set to EINTR if no data has been read. */ Buffer+= readbytes; offset+= readbytes; Count-= readbytes; continue; } my_errno= errno ? errno : -1; if (errno == 0 || (readbytes != (size_t) -1 && (MyFlags & (MY_NABP | MY_FNABP)))) my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d", (int) readbytes, (uint) Count,Filedes,my_errno)); if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR) { DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d", (int) readbytes)); continue; /* Interrupted */ } if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { char errbuf[MYSYS_STRERROR_SIZE]; if (readbytes == (size_t) -1) my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes), my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); else if (MyFlags & (MY_NABP | MY_FNABP)) my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes), my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno)); } if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP))) DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ } if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Read went ok; Return 0 */ DBUG_RETURN(total_readbytes); /* purecov: inspected */ } } /* my_pread */
size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, myf MyFlags) { size_t readbytes; int error= 0; #if !defined (HAVE_PREAD) && !defined (_WIN32) int save_errno; #endif DBUG_ENTER("my_pread"); DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d", Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags)); for (;;) { errno= 0; /* Linux, Windows don't reset this on EOF/success */ #if !defined (HAVE_PREAD) && !defined (_WIN32) mysql_mutex_lock(&my_file_info[Filedes].mutex); readbytes= (uint) -1; error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 || (readbytes= read(Filedes, Buffer, Count)) != Count); save_errno= errno; mysql_mutex_unlock(&my_file_info[Filedes].mutex); if (error) errno= save_errno; #else #if defined(_WIN32) readbytes= my_win_pread(Filedes, Buffer, Count, offset); #else readbytes= pread(Filedes, Buffer, Count, offset); #endif error= (readbytes != Count); #endif if(error) { my_errno= errno ? errno : -1; if (errno == 0 || (readbytes != (size_t) -1 && (MyFlags & (MY_NABP | MY_FNABP)))) my_errno= HA_ERR_FILE_TOO_SHORT; DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d", (int) readbytes, (uint) Count,Filedes,my_errno)); #ifdef THREAD if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR) { DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d", (int) readbytes)); continue; /* Interrupted */ } #endif if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { if (readbytes == (size_t) -1) my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),my_errno); else if (MyFlags & (MY_NABP | MY_FNABP)) my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),my_errno); } if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP))) DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ } if (MyFlags & (MY_NABP | MY_FNABP)) DBUG_RETURN(0); /* Read went ok; Return 0 */ DBUG_RETURN(readbytes); /* purecov: inspected */ } } /* my_pread */