~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_pread.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */