Updated PCI IDs to latest snapshot.
[tangerine.git] / compiler / clib / fseek.c
blob133b6ca0e6a92ad5474b05b5f7f3e8d1af1115d2
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 Change the position in a stream.
6 */
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <dos/dos.h>
11 #include <proto/dos.h>
12 #include "__errno.h"
13 #include "__stdio.h"
14 #include "__open.h"
16 /*****************************************************************************
18 NAME */
19 #include <stdio.h>
21 int fseek (
23 /* SYNOPSIS */
24 FILE * stream,
25 long offset,
26 int whence)
28 /* FUNCTION
29 Change the current position in a stream.
31 INPUTS
32 stream - Modify this stream
33 offset, whence - How to modify the current position. whence
34 can be SEEK_SET, then offset is the absolute position
35 in the file (0 is the first byte), SEEK_CUR then the
36 position will change by offset (ie. -5 means to move
37 5 bytes to the beginning of the file) or SEEK_END.
38 SEEK_END means that the offset is relative to the
39 end of the file (-1 is the last byte and 0 is
40 the EOF).
42 RESULT
43 0 on success and -1 on error. If an error occurred, the global
44 variable errno is set.
46 NOTES
48 EXAMPLE
50 BUGS
51 Not fully compatible with iso fseek, especially in 'ab' and 'a+b'
52 modes
54 SEE ALSO
55 fopen(), fwrite()
57 INTERNALS
59 ******************************************************************************/
61 int cnt = 0;
62 int finalseekposition = 0;
63 int eofposition = 0;
64 struct FileInfoBlock *fib = NULL;
65 BPTR fh = NULL;
66 fdesc *fdesc = __getfdesc(stream->fd);
68 if (!fdesc)
70 errno = EBADF;
71 return -1;
74 fh = (BPTR)(fdesc->fcb->fh);
76 /* This is buffered IO, flush the buffer before any Seek */
77 Flush (fh);
79 /* Handling for fseek specific behaviour (not all cases handled) */
80 /* Get current position */
81 cnt = Seek (fh, 0, OFFSET_CURRENT);
82 if (cnt == -1)
84 errno = IoErr2errno (IoErr ());
85 return -1;
88 /* Get file size */
89 fib = AllocDosObject(DOS_FIB, NULL);
90 if (!fib)
92 errno = IoErr2errno(IoErr());
93 return -1;
96 if (ExamineFH(fh, fib))
97 eofposition = fib->fib_Size;
98 else
100 /* Does not happen on sfs/affs */
101 FreeDosObject(DOS_FIB, fib);
102 fib = NULL;
103 errno = EBADF;
104 return -1;
107 FreeDosObject(DOS_FIB, fib);
108 fib = NULL;
110 switch(whence)
112 case SEEK_SET: finalseekposition = offset; break;
113 case SEEK_CUR: finalseekposition = cnt + offset; break;
114 case SEEK_END: finalseekposition = eofposition + offset; break;
115 default:
116 errno = EINVAL;
117 return -1;
120 /* Check conditions */
121 /* Seek before beginning of file */
122 if (finalseekposition < 0)
124 errno = EINVAL;
125 return -1;
128 /* Seek beyond end of file and in write mode */
129 if (finalseekposition > eofposition)
131 if (fdesc->fcb->flags & O_WRITE)
133 /* Write '0' to fill up to requested size - compatible fseek does not write but allows write */
134 int i = 0;
135 int bytestowrite = finalseekposition - eofposition;
136 int chunkcount = (bytestowrite)/128;
137 char zeroarray[128] = {0};
139 Seek (fh, 0, OFFSET_END);
140 for (i = 0; i < chunkcount; i++)
141 FWrite(fh, (STRPTR)zeroarray, 128, 1);
142 FWrite(fh, (STRPTR)zeroarray, bytestowrite - (chunkcount * 128), 1);
143 Flush (fh);
147 cnt = Seek (fh, finalseekposition, OFFSET_BEGINNING);
149 if (cnt == -1)
150 errno = IoErr2errno (IoErr ());
151 else
152 cnt = 0;
154 return cnt;
155 } /* fseek */