1 // Copyright (c) 2000, 2015, 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, version 2.0, as
5 // published by the Free Software Foundation.
6 //
7 // This program is also distributed with certain software (including
8 // but not limited to OpenSSL) that is licensed under separate terms,
9 // as designated in a particular file or component or in included license
10 // documentation. The authors of MySQL hereby grant you an
11 // additional permission to link the program and your derivative works
12 // with the separately licensed software that they have included with
13 // MySQL.
14 //
15 // Without limiting anything contained in the foregoing, this file,
16 // which is part of <MySQL Product>, is also subject to the
17 // Universal FOSS Exception, version 1.0, a copy of which can be found at
18 // http://oss.oracle.com/licenses/universal-foss-exception.
19 //
20 // This program is distributed in the hope that it will be useful, but
21 // WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 // See the GNU General Public License, version 2.0, for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with this program; if not, write to the Free Software Foundation, Inc.,
27 // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 
29 #include "mysys_priv.h"
30 #include "my_sys.h"
31 #include "mysys_err.h"
32 #include <my_base.h>
33 #include <errno.h>
34 #include "my_thread_local.h"
35 
36 /*
37   Read a chunk of bytes from a file with retry's if needed
38 
39   The parameters are:
40     File descriptor
41     Buffer to hold at least Count bytes
42     Bytes to read
43     Flags on what to do on error
44 
45     Return:
46       -1 on error
47       0  if flag has bits MY_NABP or MY_FNABP set
48       N  number of bytes read.
49 */
50 
my_read(File Filedes,uchar * Buffer,size_t Count,myf MyFlags)51 size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
52 {
53   size_t readbytes, save_count;
54   DBUG_ENTER("my_read");
55   DBUG_PRINT("my",("fd: %d  Buffer: %p  Count: %lu  MyFlags: %d",
56                    Filedes, Buffer, (ulong) Count, MyFlags));
57   save_count= Count;
58 
59   for (;;)
60   {
61     errno= 0;					/* Linux, Windows don't reset this on EOF/success */
62 #ifdef _WIN32
63     readbytes= my_win_read(Filedes, Buffer, Count);
64 #else
65     readbytes= read(Filedes, Buffer, Count);
66 #endif
67     DBUG_EXECUTE_IF ("simulate_file_read_error",
68                      {
69                        errno= ENOSPC;
70                        readbytes= (size_t) -1;
71                        DBUG_SET("-d,simulate_file_read_error");
72                        DBUG_SET("-d,simulate_my_b_fill_error");
73                      });
74 
75     if (readbytes != Count)
76     {
77       set_my_errno(errno);
78       if (errno == 0 || (readbytes != (size_t) -1 &&
79                          (MyFlags & (MY_NABP | MY_FNABP))))
80         set_my_errno(HA_ERR_FILE_TOO_SHORT);
81       DBUG_PRINT("warning",("Read only %d bytes off %lu from %d, errno: %d",
82                             (int) readbytes, (ulong) Count, Filedes,
83                             my_errno()));
84 
85       if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR)
86       {
87         DBUG_PRINT("debug", ("my_read() was interrupted and returned %ld",
88                              (long) readbytes));
89         continue;                              /* Interrupted */
90       }
91 
92       if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
93       {
94         char errbuf[MYSYS_STRERROR_SIZE];
95         if (readbytes == (size_t) -1)
96           mysys_error(EE_READ, MYF(0), my_filename(Filedes),
97                    my_errno(), mysys_strerror(errbuf, sizeof(errbuf), my_errno()));
98         else if (MyFlags & (MY_NABP | MY_FNABP))
99           mysys_error(EE_EOFERR, MYF(0), my_filename(Filedes),
100                    my_errno(), mysys_strerror(errbuf, sizeof(errbuf), my_errno()));
101       }
102       if (readbytes == (size_t) -1 ||
103           ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
104         DBUG_RETURN(MY_FILE_ERROR);	/* Return with error */
105       if (readbytes != (size_t) -1 && (MyFlags & MY_FULL_IO))
106       {
107         Buffer+= readbytes;
108         Count-= readbytes;
109         continue;
110       }
111     }
112 
113     if (MyFlags & (MY_NABP | MY_FNABP))
114       readbytes= 0;			/* Ok on read */
115     else if (MyFlags & MY_FULL_IO)
116       readbytes= save_count;
117     break;
118   }
119   DBUG_RETURN(readbytes);
120 } /* my_read */
121