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-1335  USA */
15 
16 /* USE_MY_STREAM isn't set because we can't thrust my_fclose! */
17 
18 #include "mysys_priv.h"
19 #include "mysys_err.h"
20 #include <errno.h>
21 #include <stdio.h>
22 
23 #ifdef HAVE_FSEEKO
24 #undef ftell
25 #undef fseek
26 #define ftell(A) ftello(A)
27 #define fseek(A,B,C) fseeko((A),(B),(C))
28 #endif
29 
30 /*
31   Read a chunk of bytes from a FILE
32 
33   SYNOPSIS
34    my_fread()
35    stream	File descriptor
36    Buffer	Buffer to read to
37    Count	Number of bytes to read
38    MyFlags	Flags on what to do on error
39 
40   RETURN
41     (size_t) -1 Error
42     #		Number of bytes read
43  */
44 
my_fread(FILE * stream,uchar * Buffer,size_t Count,myf MyFlags)45 size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags)
46 {
47   size_t readbytes;
48   DBUG_ENTER("my_fread");
49   DBUG_PRINT("my",("stream: %p  Buffer %p  Count: %u  MyFlags: %lu",
50 		   stream, Buffer, (uint) Count, MyFlags));
51 
52   if ((readbytes= fread(Buffer, sizeof(char), Count, stream)) != Count)
53   {
54     DBUG_PRINT("error",("Read only %d bytes", (int) readbytes));
55     if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
56     {
57       if (ferror(stream))
58 	my_error(EE_READ, MYF(ME_BELL),
59 		 my_filename(my_fileno(stream)),errno);
60       else
61       if (MyFlags & (MY_NABP | MY_FNABP))
62 	my_error(EE_EOFERR, MYF(ME_BELL),
63 		 my_filename(my_fileno(stream)),errno);
64     }
65     my_errno=errno ? errno : -1;
66     if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
67       DBUG_RETURN((size_t) -1);			/* Return with error */
68   }
69   if (MyFlags & (MY_NABP | MY_FNABP))
70     DBUG_RETURN(0);				/* Read ok */
71   DBUG_RETURN(readbytes);
72 } /* my_fread */
73 
74 
75 /*
76   Write a chunk of bytes to a stream
77 
78    my_fwrite()
79    stream	File descriptor
80    Buffer	Buffer to write from
81    Count	Number of bytes to write
82    MyFlags	Flags on what to do on error
83 
84   RETURN
85     (size_t) -1 Error
86     #		Number of bytes written
87 */
88 
my_fwrite(FILE * stream,const uchar * Buffer,size_t Count,myf MyFlags)89 size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags)
90 {
91   size_t writtenbytes =0;
92   my_off_t seekptr;
93 #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
94   uint errors;
95 #endif
96   DBUG_ENTER("my_fwrite");
97   DBUG_PRINT("my",("stream:%p  Buffer:%p  Count: %u  MyFlags: %lu",
98 		   stream, Buffer, (uint) Count, MyFlags));
99 
100 #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
101   errors=0;
102 #endif
103   seekptr= ftell(stream);
104   for (;;)
105   {
106     size_t written;
107     if ((written = (size_t) fwrite((char*) Buffer,sizeof(char),
108                                    Count, stream)) != Count)
109     {
110       DBUG_PRINT("error",("Write only %d bytes", (int) writtenbytes));
111       my_errno=errno;
112       if (written != (size_t) -1)
113       {
114 	seekptr+=written;
115 	Buffer+=written;
116 	writtenbytes+=written;
117 	Count-=written;
118       }
119 #ifdef EINTR
120       if (errno == EINTR)
121       {
122 	(void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
123 	continue;
124       }
125 #endif
126 #if !defined(NO_BACKGROUND) && defined(USE_MY_STREAM)
127       if (my_thread_var->abort)
128 	MyFlags&= ~ MY_WAIT_IF_FULL;		/* End if aborted by user */
129 
130       if ((errno == ENOSPC || errno == EDQUOT) &&
131           (MyFlags & MY_WAIT_IF_FULL))
132       {
133         wait_for_free_space("[stream]", errors);
134         errors++;
135         (void) my_fseek(stream,seekptr,MY_SEEK_SET,MYF(0));
136         continue;
137       }
138 #endif
139       if (ferror(stream) || (MyFlags & (MY_NABP | MY_FNABP)))
140       {
141 	if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
142 	{
143 	  my_error(EE_WRITE, MYF(ME_BELL),
144 		   my_filename(my_fileno(stream)), errno);
145 	}
146 	writtenbytes= (size_t) -1;        /* Return that we got error */
147 	break;
148       }
149     }
150     if (MyFlags & (MY_NABP | MY_FNABP))
151       writtenbytes= 0;				/* Everything OK */
152     else
153       writtenbytes+= written;
154     break;
155   }
156   DBUG_RETURN(writtenbytes);
157 } /* my_fwrite */
158 
159 
160 /* Seek to position in file */
161 
my_fseek(FILE * stream,my_off_t pos,int whence,myf MyFlags)162 my_off_t my_fseek(FILE *stream, my_off_t pos, int whence,
163 		  myf MyFlags __attribute__((unused)))
164 {
165   DBUG_ENTER("my_fseek");
166   DBUG_PRINT("my",("stream:%p  pos: %llu  whence: %d  MyFlags: %lu",
167                    stream, (ulonglong) pos, whence, MyFlags));
168   DBUG_RETURN(fseek(stream, (off_t) pos, whence) ?
169 	      MY_FILEPOS_ERROR : (my_off_t) ftell(stream));
170 } /* my_seek */
171 
172 
173 /* Tell current position of file */
174 
my_ftell(FILE * stream,myf MyFlags)175 my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
176 {
177   long long pos;
178   DBUG_ENTER("my_ftell");
179   DBUG_PRINT("my",("stream:%p  MyFlags: %lu", stream, MyFlags));
180   pos=IF_WIN(_ftelli64(stream),ftell(stream));
181   DBUG_PRINT("exit",("ftell: %lld",pos));
182   DBUG_RETURN((my_off_t) pos);
183 } /* my_ftell */
184 
185 
186 /* Get a File corresponding to the stream*/
my_fileno(FILE * f)187 int my_fileno(FILE *f)
188 {
189 #ifdef _WIN32
190   return my_win_fileno(f);
191 #else
192  return fileno(f);
193 #endif
194 }
195