2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Change the position in a stream.
11 #include <proto/dos.h>
15 /*****************************************************************************
28 Change the current position in a stream.
31 stream - Modify this stream
32 offset, whence - How to modify the current position. whence
33 can be SEEK_SET, then offset is the absolute position
34 in the file (0 is the first byte), SEEK_CUR then the
35 position will change by offset (ie. -5 means to move
36 5 bytes to the beginning of the file) or SEEK_END.
37 SEEK_END means that the offset is relative to the
38 end of the file (-1 is the last byte and 0 is
42 0 on success and -1 on error. If an error occurred, the global
43 variable errno is set.
51 Not fully compatible with iso fseeko, especially in 'ab' and 'a+b'
58 just a hack, not 64-bit
60 ******************************************************************************/
63 off_t finalseekposition
= 0;
64 off_t eofposition
= 0;
65 struct FileInfoBlock
*fib
= NULL
;
67 fdesc
*fdesc
= __getfdesc(stream
->fd
);
75 fh
= fdesc
->fcb
->handle
;
77 /* This is buffered IO, flush the buffer before any Seek */
80 /* Handling for fseeko specific behaviour (not all cases handled) */
81 /* Get current position */
82 cnt
= Seek (fh
, 0, OFFSET_CURRENT
);
85 errno
= __stdc_ioerr2errno (IoErr ());
90 fib
= AllocDosObject(DOS_FIB
, NULL
);
93 errno
= __stdc_ioerr2errno(IoErr());
97 if (ExamineFH(fh
, fib
))
98 eofposition
= fib
->fib_Size
;
101 /* Does not happen on sfs/affs */
102 FreeDosObject(DOS_FIB
, fib
);
108 FreeDosObject(DOS_FIB
, fib
);
113 case SEEK_SET
: finalseekposition
= offset
; break;
114 case SEEK_CUR
: finalseekposition
= cnt
+ offset
; break;
115 case SEEK_END
: finalseekposition
= eofposition
+ offset
; break;
121 /* Check conditions */
122 /* Seek before beginning of file */
123 if (finalseekposition
< 0)
129 /* Seek beyond end of file and in write mode */
130 if (finalseekposition
> eofposition
)
132 if (fdesc
->fcb
->flags
& O_WRITE
)
134 /* Write '0' to fill up to requested size
135 * compatible fseeko does not write but allows write */
136 int bytestowrite
= finalseekposition
- eofposition
;
137 int chunkcount
= (bytestowrite
)/128;
138 int remainder
= bytestowrite
- (chunkcount
* 128);
139 char zeroarray
[128] = {0};
141 Seek (fh
, 0, OFFSET_END
);
143 FWrite (fh
, zeroarray
, 128, chunkcount
);
145 FWrite (fh
, zeroarray
, remainder
, 1);
150 cnt
= Seek (fh
, finalseekposition
, OFFSET_BEGINNING
);
153 errno
= __stdc_ioerr2errno (IoErr ());
156 /* It's specified that upon success fseeko should clear EOF flag
159 stream
->flags
&= ~(__POSIXC_STDIO_EOF
);