MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
my_pread.c
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "mysys_priv.h"
17 #include "mysys_err.h"
18 #include "my_base.h"
19 #include <m_string.h>
20 #include <errno.h>
21 #if defined (HAVE_PREAD) && !defined(_WIN32)
22 #include <unistd.h>
23 #endif
24 
25 
26 
27 /*
28  Read a chunk of bytes from a file from a given position
29 
30  SYNOPSIOS
31  my_pread()
32  Filedes File decsriptor
33  Buffer Buffer to read data into
34  Count Number of bytes to read
35  offset Position to read from
36  MyFlags Flags
37 
38  NOTES
39  This differs from the normal pread() call in that we don't care
40  to set the position in the file back to the original position
41  if the system doesn't support pread().
42 
43  RETURN
44  (size_t) -1 Error
45  # Number of bytes read
46 */
47 
48 size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
49  myf MyFlags)
50 {
51  size_t readbytes;
52  int error= 0;
53 #if !defined (HAVE_PREAD) && !defined (_WIN32)
54  int save_errno;
55 #endif
56  DBUG_ENTER("my_pread");
57  DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
58  Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
59  for (;;)
60  {
61  errno= 0; /* Linux, Windows don't reset this on EOF/success */
62 #if !defined (HAVE_PREAD) && !defined (_WIN32)
63  mysql_mutex_lock(&my_file_info[Filedes].mutex);
64  readbytes= (uint) -1;
65  error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
66  (readbytes= read(Filedes, Buffer, Count)) != Count);
67  save_errno= errno;
68  mysql_mutex_unlock(&my_file_info[Filedes].mutex);
69  if (error)
70  errno= save_errno;
71 #else
72 #if defined(_WIN32)
73  readbytes= my_win_pread(Filedes, Buffer, Count, offset);
74 #else
75  readbytes= pread(Filedes, Buffer, Count, offset);
76 #endif
77  error= (readbytes != Count);
78 #endif
79  if(error)
80  {
81  my_errno= errno ? errno : -1;
82  if (errno == 0 || (readbytes != (size_t) -1 &&
83  (MyFlags & (MY_NABP | MY_FNABP))))
84  my_errno= HA_ERR_FILE_TOO_SHORT;
85 
86  DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
87  (int) readbytes, (uint) Count,Filedes,my_errno));
88 
89  if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
90  {
91  DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
92  (int) readbytes));
93  continue; /* Interrupted */
94  }
95 
96  if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
97  {
98  char errbuf[MYSYS_STRERROR_SIZE];
99  if (readbytes == (size_t) -1)
100  my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),
101  my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
102  else if (MyFlags & (MY_NABP | MY_FNABP))
103  my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), my_filename(Filedes),
104  my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
105  }
106  if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
107  DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
108  }
109  if (MyFlags & (MY_NABP | MY_FNABP))
110  DBUG_RETURN(0); /* Read went ok; Return 0 */
111  DBUG_RETURN(readbytes); /* purecov: inspected */
112  }
113 } /* my_pread */
114 
115 
116 /*
117  Write a chunk of bytes to a file at a given position
118 
119  SYNOPSIOS
120  my_pwrite()
121  Filedes File decsriptor
122  Buffer Buffer to write data from
123  Count Number of bytes to write
124  offset Position to write to
125  MyFlags Flags
126 
127  NOTES
128  This differs from the normal pwrite() call in that we don't care
129  to set the position in the file back to the original position
130  if the system doesn't support pwrite()
131 
132  RETURN
133  (size_t) -1 Error
134  # Number of bytes read
135 */
136 
137 size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count,
138  my_off_t offset, myf MyFlags)
139 {
140  size_t writtenbytes, written;
141  uint errors;
142 
143  DBUG_ENTER("my_pwrite");
144  DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
145  Filedes, offset, Buffer, (ulong)Count, MyFlags));
146  errors= 0;
147  written= 0;
148 
149  for (;;)
150  {
151 #if !defined (HAVE_PREAD) && !defined (_WIN32)
152  int error;
153  writtenbytes= (size_t) -1;
154  mysql_mutex_lock(&my_file_info[Filedes].mutex);
155  error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
156  (writtenbytes= write(Filedes, Buffer, Count)) == Count);
157  mysql_mutex_unlock(&my_file_info[Filedes].mutex);
158  if (error)
159  break;
160 #elif defined (_WIN32)
161  writtenbytes= my_win_pwrite(Filedes, Buffer, Count, offset);
162 #else
163  writtenbytes= pwrite(Filedes, Buffer, Count, offset);
164 #endif
165  if(writtenbytes == Count)
166  break;
167  my_errno= errno;
168  if (writtenbytes != (size_t) -1)
169  {
170  written+= writtenbytes;
171  Buffer+= writtenbytes;
172  Count-= writtenbytes;
173  offset+= writtenbytes;
174  }
175  DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
176 #ifndef NO_BACKGROUND
177 
178  if (my_thread_var->abort)
179  MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
180 
181  if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
182  (MyFlags & MY_WAIT_IF_FULL))
183  {
184  wait_for_free_space(my_filename(Filedes), errors);
185  errors++;
186  continue;
187  }
188  if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR)
189  continue; /* Retry */
190 #endif
191  if (MyFlags & (MY_NABP | MY_FNABP))
192  {
193  if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
194  {
195  char errbuf[MYSYS_STRERROR_SIZE];
196  my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG), my_filename(Filedes),
197  my_errno, my_strerror(errbuf, sizeof(errbuf), my_errno));
198  }
199  DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
200  }
201  else
202  break; /* Return bytes written */
203  }
204  DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
205  if (MyFlags & (MY_NABP | MY_FNABP))
206  DBUG_RETURN(0); /* Want only errors */
207  DBUG_RETURN(writtenbytes+written); /* purecov: inspected */
208 } /* my_pwrite */