~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
#include "mysys_priv.h"
17
#include "mysys_err.h"
18
#include <errno.h>
19
#ifdef HAVE_PREAD
20
#include <unistd.h>
21
#endif
22
23
/*
24
  Read a chunk of bytes from a file from a given position
25
26
  SYNOPSIOS
27
    my_pread()
28
    Filedes	File decsriptor
29
    Buffer	Buffer to read data into
30
    Count	Number of bytes to read
31
    offset	Position to read from
32
    MyFlags	Flags
33
34
  NOTES
35
    This differs from the normal pread() call in that we don't care
36
    to set the position in the file back to the original position
37
    if the system doesn't support pread().
38
39
  RETURN
40
    (size_t) -1   Error
41
    #             Number of bytes read
42
*/
43
44
size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
45
                myf MyFlags)
46
{
47
  size_t readbytes;
48
  int error= 0;
49
  DBUG_ENTER("my_pread");
50
  DBUG_PRINT("my",("Fd: %d  Seek: %lu  Buffer: 0x%lx  Count: %u  MyFlags: %d",
51
		   Filedes, (ulong) offset, (long) Buffer, (uint) Count,
52
                   MyFlags));
53
  for (;;)
54
  {
55
    errno=0;					/* Linux doesn't reset this */
56
#ifndef HAVE_PREAD
57
    pthread_mutex_lock(&my_file_info[Filedes].mutex);
58
    readbytes= (uint) -1;
59
    error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
60
	    (readbytes= read(Filedes, Buffer, Count)) != Count);
61
    pthread_mutex_unlock(&my_file_info[Filedes].mutex);
62
#else
63
    if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
64
      my_errno= errno ? errno : -1;
65
#endif
66
    if (error || readbytes != Count)
67
    {
68
      DBUG_PRINT("warning",("Read only %d bytes off %u from %d, errno: %d",
69
                            (int) readbytes, (uint) Count,Filedes,my_errno));
70
#ifdef THREAD
71
      if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
72
      {
73
        DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d",
74
                             (int) readbytes));
75
        continue;                              /* Interrupted */
76
      }
77
#endif
78
      if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
79
      {
80
	if (readbytes == (size_t) -1)
81
	  my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
82
		   my_filename(Filedes),my_errno);
83
	else if (MyFlags & (MY_NABP | MY_FNABP))
84
	  my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
85
		   my_filename(Filedes),my_errno);
86
      }
87
      if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
88
	DBUG_RETURN(MY_FILE_ERROR);		/* Return with error */
89
    }
90
    if (MyFlags & (MY_NABP | MY_FNABP))
91
      DBUG_RETURN(0);				/* Read went ok; Return 0 */
92
    DBUG_RETURN(readbytes);			/* purecov: inspected */
93
  }
94
} /* my_pread */
95
96
97
/*
98
  Write a chunk of bytes to a file at a given position
99
100
  SYNOPSIOS
101
    my_pwrite()
102
    Filedes	File decsriptor
103
    Buffer	Buffer to write data from
104
    Count	Number of bytes to write
105
    offset	Position to write to
106
    MyFlags	Flags
107
108
  NOTES
109
    This differs from the normal pwrite() call in that we don't care
110
    to set the position in the file back to the original position
111
    if the system doesn't support pwrite()
112
113
  RETURN
114
    (size_t) -1   Error
115
    #             Number of bytes read
116
*/
117
118
size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
119
                 my_off_t offset, myf MyFlags)
120
{
121
  size_t writenbytes, written;
122
  uint errors;
123
  DBUG_ENTER("my_pwrite");
124
  DBUG_PRINT("my",("Fd: %d  Seek: %lu  Buffer: 0x%lx  Count: %u  MyFlags: %d",
125
		   Filedes, (ulong) offset, (long) Buffer, (uint) Count,
126
                   MyFlags));
127
  errors= 0;
128
  written= 0;
129
130
  for (;;)
131
  {
132
#ifndef HAVE_PREAD
133
    int error;
134
    writenbytes= (size_t) -1;
135
    pthread_mutex_lock(&my_file_info[Filedes].mutex);
136
    error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
137
            (writenbytes = write(Filedes, Buffer, Count)) == Count);
138
    pthread_mutex_unlock(&my_file_info[Filedes].mutex);
139
    if (error)
140
      break;
141
#else
142
    if ((writenbytes= pwrite(Filedes, Buffer, Count,offset)) == Count)
143
      break;
144
    my_errno= errno;
145
#endif
146
    if (writenbytes != (size_t) -1)
147
    {					/* Safegueard */
148
      written+=writenbytes;
149
      Buffer+=writenbytes;
150
      Count-=writenbytes;
151
      offset+=writenbytes;
152
    }
153
    DBUG_PRINT("error",("Write only %u bytes", (uint) writenbytes));
154
#ifndef NO_BACKGROUND
155
#ifdef THREAD
156
    if (my_thread_var->abort)
157
      MyFlags&= ~ MY_WAIT_IF_FULL;		/* End if aborted by user */
158
#endif
159
    if ((my_errno == ENOSPC || my_errno == EDQUOT) &&
160
        (MyFlags & MY_WAIT_IF_FULL))
161
    {
162
      if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE))
163
	my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
164
		 my_filename(Filedes),my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
165
      VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
166
      continue;
167
    }
168
    if ((writenbytes && writenbytes != (size_t) -1) || my_errno == EINTR)
169
      continue;					/* Retry */
170
#endif
171
    if (MyFlags & (MY_NABP | MY_FNABP))
172
    {
173
      if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
174
      {
175
	my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG),
176
		 my_filename(Filedes),my_errno);
177
      }
178
      DBUG_RETURN(MY_FILE_ERROR);		/* Error on read */
179
    }
180
    else
181
      break;					/* Return bytes written */
182
  }
183
  DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
184
  if (MyFlags & (MY_NABP | MY_FNABP))
185
    DBUG_RETURN(0);			/* Want only errors */
186
  DBUG_RETURN(writenbytes+written); /* purecov: inspected */
187
} /* my_pwrite */