Example #1
0
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 */
Example #2
0
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 */
Example #3
0
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 */