dos.library: Possibly uninitialized 'res', and divide by zero if blocklen = 0
[AROS.git] / rom / dos / fread.c
blobf3b4a592b24f98562c0601ae6dbccd54809bb2dc
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <aros/debug.h>
10 #include "dos_intern.h"
12 #define FETCHERR (-2)
14 /*****************************************************************************
16 NAME */
17 #include <proto/dos.h>
19 AROS_LH4(LONG, FRead,
21 /* SYNOPSIS */
22 AROS_LHA(BPTR , fh, D1),
23 AROS_LHA(APTR , block, D2),
24 AROS_LHA(ULONG, blocklen, D3),
25 AROS_LHA(ULONG, number, D4),
27 /* LOCATION */
28 struct DosLibrary *, DOSBase, 54, Dos)
30 /* FUNCTION
31 Read a number of blocks from a file.
33 INPUTS
34 fh - Read from this file
35 block - The data is put here
36 blocklen - This is the size of a single block
37 number - The number of blocks
39 RESULT
40 The number of blocks read from the file or 0 on EOF.
41 This function may return fewer than the requested number of blocks.
42 IoErr() gives additional information in case of an error.
44 NOTES
46 EXAMPLE
48 BUGS
50 SEE ALSO
51 Open(), FWrite(), FPutc(), Close()
53 INTERNALS
55 *****************************************************************************/
57 AROS_LIBFUNC_INIT
59 UBYTE *ptr;
60 LONG res = FETCHERR;
61 LONG fetchsize = number * blocklen;
62 LONG readsize;
64 ptr = block;
66 SetIoErr(0);
68 if (fetchsize == 0)
69 return 0;
71 while(fetchsize > 0)
73 res = vbuf_fetch(fh, ptr, fetchsize, DOSBase);
74 if (res < 0)
75 break;
76 ptr += res;
77 fetchsize -= res;
80 if(res == FETCHERR)
82 return EOF;
85 readsize = (LONG)(ptr - (UBYTE *)block);
88 return readsize / blocklen;
90 AROS_LIBFUNC_EXIT
91 } /* FRead */
93 static LONG handle_write_mode(BPTR file, struct DosLibrary * DOSBase)
95 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
97 /* If the file is in write mode... */
98 if(fh->fh_Flags & FHF_WRITE)
100 /* write the buffer (in many pieces if the first one isn't enough). */
101 LONG pos = 0;
103 while(pos != fh->fh_Pos)
105 LONG size = Write(file, BADDR(fh->fh_Buf) + pos, fh->fh_Pos - pos);
107 /* An error happened? Return it. */
108 if(size < 0)
110 return FETCHERR;
113 pos += size;
116 /* Reinit filehandle. */
117 fh->fh_Flags &= ~FHF_WRITE;
118 fh->fh_Pos = fh->fh_End = 0;
121 return 0;
124 /* Fetches up to remaining buffer content from file buffer
125 * Return values:
126 * (-2) on error
127 * (EOF) on EOF
128 * (>0) on sucesfull fetch
130 LONG vbuf_fetch(BPTR file, UBYTE * buffer, LONG fetchsize, struct DosLibrary *DOSBase)
132 /* Get pointer to filehandle */
133 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
135 LONG size;
136 LONG bufsize;
138 if (fh == NULL)
140 return FETCHERR;
143 if (handle_write_mode(file, DOSBase) == FETCHERR)
145 return FETCHERR;
148 /* No normal characters left. */
149 if(fh->fh_Pos >= fh->fh_End)
151 /* Check for a pushed back EOF. */
152 if(fh->fh_Pos > fh->fh_End)
154 D(bug("FGetC: Weird pos: fh_Pos (%d) > fh_End (%d)\n", fh->fh_Pos, fh->fh_End));
155 /* Return EOF. */
156 return EOF;
159 /* Is there a buffer? */
160 if(fh->fh_Buf == BNULL)
162 if (NULL == vbuf_alloc(fh, NULL, IOBUFSIZE))
164 D(bug("FGetC: Can't allocate buffer\n"));
165 return FETCHERR;
169 /* Fill the buffer. */
170 if (fh->fh_Buf != fh->fh_OrigBuf) {
171 D(bug("FGetC: Can't trust fh_BufSize. Using 208 as the buffer size.\n"));
172 bufsize = 208;
173 } else {
174 bufsize = fh->fh_BufSize;
176 size = Read(file, BADDR(fh->fh_Buf), bufsize);
178 /* Prepare filehandle for data. */
179 if(size <= 0)
180 size = 0;
182 fh->fh_Pos = 0;
183 fh->fh_End = size;
185 /* No data read? Return EOF. */
186 if(size == 0)
188 D(bug("FGetC: Tried to Read() to a %d byte buffer, got 0)\n", bufsize));
189 return EOF;
193 /* If fh_End == 0, simulate an EOF */
194 if (fh->fh_End == 0) {
195 D(bug("FGetC: Got an EOF via fh_End == 0\n"));
196 return EOF;
199 /* All OK. Get requested data. */
200 size = fh->fh_End - fh->fh_Pos;
201 if (size > fetchsize) size = fetchsize;
202 if (size == 1) /* Don't do function call for 1 byte reads */
203 *buffer = ((UBYTE *)BADDR(fh->fh_Buf))[fh->fh_Pos];
204 else
205 CopyMem(((UBYTE *)BADDR(fh->fh_Buf)) + fh->fh_Pos, buffer, size);
207 fh->fh_Pos += size;
209 return size;