2 Copyright © 1995-2012, 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.
50 Not fully compatible with iso fseek, especially in 'ab' and 'a+b'
58 ******************************************************************************/
61 int finalseekposition
= 0;
63 struct FileInfoBlock
*fib
= NULL
;
65 fdesc
*fdesc
= __getfdesc(stream
->fd
);
73 fh
= (BPTR
)(fdesc
->fcb
->fh
);
75 /* This is buffered IO, flush the buffer before any Seek */
78 /* Handling for fseek specific behaviour (not all cases handled) */
79 /* Get current position */
80 cnt
= Seek (fh
, 0, OFFSET_CURRENT
);
83 errno
= __arosc_ioerr2errno (IoErr ());
88 fib
= AllocDosObject(DOS_FIB
, NULL
);
91 errno
= __arosc_ioerr2errno(IoErr());
95 if (ExamineFH(fh
, fib
))
96 eofposition
= fib
->fib_Size
;
99 /* Does not happen on sfs/affs */
100 FreeDosObject(DOS_FIB
, fib
);
106 FreeDosObject(DOS_FIB
, fib
);
111 case SEEK_SET
: finalseekposition
= offset
; break;
112 case SEEK_CUR
: finalseekposition
= cnt
+ offset
; break;
113 case SEEK_END
: finalseekposition
= eofposition
+ offset
; break;
119 /* Check conditions */
120 /* Seek before beginning of file */
121 if (finalseekposition
< 0)
127 /* Seek beyond end of file and in write mode */
128 if (finalseekposition
> eofposition
)
130 if (fdesc
->fcb
->flags
& O_WRITE
)
132 /* Write '0' to fill up to requested size - compatible fseek does not write but allows write */
134 int bytestowrite
= finalseekposition
- eofposition
;
135 int chunkcount
= (bytestowrite
)/128;
136 char zeroarray
[128] = {0};
138 Seek (fh
, 0, OFFSET_END
);
139 for (i
= 0; i
< chunkcount
; i
++)
140 FWrite(fh
, (STRPTR
)zeroarray
, 128, 1);
141 FWrite(fh
, (STRPTR
)zeroarray
, bytestowrite
- (chunkcount
* 128), 1);
146 cnt
= Seek (fh
, finalseekposition
, OFFSET_BEGINNING
);
149 errno
= __arosc_ioerr2errno (IoErr ());
152 /* It's specified that upon success fseek should clear EOF flag
155 stream
->flags
&= ~(_STDIO_EOF
);