Drizzled Public API Documentation

my_pread.cc

00001 /* Copyright (C) 2000 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 #include "myisam_priv.h"
00017 #include <drizzled/error.h>
00018 #include <cerrno>
00019 #include <unistd.h>
00020 
00021 using namespace drizzled;
00022 
00023 /*
00024   Read a chunk of bytes from a file from a given position
00025 
00026   SYNOPSIOS
00027     my_pread()
00028     Filedes File decsriptor
00029     Buffer  Buffer to read data into
00030     Count Number of bytes to read
00031     offset  Position to read from
00032     MyFlags Flags
00033 
00034   NOTES
00035     This differs from the normal pread() call in that we don't care
00036     to set the position in the file back to the original position
00037     if the system doesn't support pread().
00038 
00039   RETURN
00040     (size_t) -1   Error
00041     #             Number of bytes read
00042 */
00043 
00044 size_t my_pread(int Filedes, unsigned char *Buffer, size_t Count, internal::my_off_t offset,
00045                 myf MyFlags)
00046 {
00047   size_t readbytes;
00048   int error= 0;
00049   for (;;)
00050   {
00051     errno=0;          /* Linux doesn't reset this */
00052     if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
00053       errno= errno ? errno : -1;
00054     if (error || readbytes != Count)
00055     {
00056       if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
00057       {
00058         continue;                              /* Interrupted */
00059       }
00060       if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
00061       {
00062   if (readbytes == (size_t) -1)
00063     my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), "unknown", errno);
00064   else if (MyFlags & (MY_NABP | MY_FNABP))
00065     my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), "unknown", errno);
00066       }
00067       if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
00068   return(MY_FILE_ERROR);    /* Return with error */
00069     }
00070     if (MyFlags & (MY_NABP | MY_FNABP))
00071       return(0);        /* Read went ok; Return 0 */
00072     return(readbytes);
00073   }
00074 } /* my_pread */
00075 
00076 
00077 /*
00078   Write a chunk of bytes to a file at a given position
00079 
00080   SYNOPSIOS
00081     my_pwrite()
00082     Filedes File decsriptor
00083     Buffer  Buffer to write data from
00084     Count Number of bytes to write
00085     offset  Position to write to
00086     MyFlags Flags
00087 
00088   NOTES
00089     This differs from the normal pwrite() call in that we don't care
00090     to set the position in the file back to the original position
00091     if the system doesn't support pwrite()
00092 
00093   RETURN
00094     (size_t) -1   Error
00095     #             Number of bytes read
00096 */
00097 
00098 size_t my_pwrite(int Filedes, const unsigned char *Buffer, size_t Count,
00099                  internal::my_off_t offset, myf MyFlags)
00100 {
00101   size_t writenbytes, written;
00102   uint32_t errors;
00103   errors= 0;
00104   written= 0;
00105 
00106   for (;;)
00107   {
00108     if ((writenbytes= pwrite(Filedes, Buffer, Count,offset)) == Count)
00109       break;
00110     errno= errno;
00111     if (writenbytes != (size_t) -1)
00112     {         /* Safegueard */
00113       written+=writenbytes;
00114       Buffer+=writenbytes;
00115       Count-=writenbytes;
00116       offset+=writenbytes;
00117     }
00118 #ifndef NO_BACKGROUND
00119     if ((errno == ENOSPC || errno == EDQUOT) &&
00120         (MyFlags & MY_WAIT_IF_FULL))
00121     {
00122       if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE))
00123   my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
00124      "unknown", errno, MY_WAIT_FOR_USER_TO_FIX_PANIC);
00125       sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
00126       continue;
00127     }
00128     if ((writenbytes && writenbytes != (size_t) -1) || errno == EINTR)
00129       continue;         /* Retry */
00130 #endif
00131     if (MyFlags & (MY_NABP | MY_FNABP))
00132     {
00133       if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
00134       {
00135   my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), "unknown", errno);
00136       }
00137       return(MY_FILE_ERROR);    /* Error on read */
00138     }
00139     else
00140       break;          /* Return bytes written */
00141   }
00142   if (MyFlags & (MY_NABP | MY_FNABP))
00143     return(0);      /* Want only errors */
00144   return(writenbytes+written);
00145 } /* my_pwrite */