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.
50 Not fully compatible with iso fseek, especially in 'ab' and 'a+b'
53 Since it's not possible to use Seek() for directories, this
54 implementation fails with EISDIR for directory file descriptors.
61 ******************************************************************************/
64 int finalseekposition
= 0;
66 struct FileInfoBlock
*fib
= NULL
;
68 fdesc
*fdesc
= __getfdesc(stream
->fd
);
76 if (fdesc
->fcb
->privflags
& _FCB_ISDIR
)
82 fh
= fdesc
->fcb
->handle
;
84 /* This is buffered IO, flush the buffer before any Seek */
87 /* Handling for fseek specific behaviour (not all cases handled) */
88 /* Get current position */
89 cnt
= Seek (fh
, 0, OFFSET_CURRENT
);
92 errno
= __stdc_ioerr2errno (IoErr ());
97 fib
= AllocDosObject(DOS_FIB
, NULL
);
100 errno
= __stdc_ioerr2errno(IoErr());
104 if (ExamineFH(fh
, fib
))
105 eofposition
= fib
->fib_Size
;
108 /* Does not happen on sfs/affs */
109 FreeDosObject(DOS_FIB
, fib
);
115 FreeDosObject(DOS_FIB
, fib
);
120 case SEEK_SET
: finalseekposition
= offset
; break;
121 case SEEK_CUR
: finalseekposition
= cnt
+ offset
; break;
122 case SEEK_END
: finalseekposition
= eofposition
+ offset
; break;
128 /* Check conditions */
129 /* Seek before beginning of file */
130 if (finalseekposition
< 0)
136 /* Seek beyond end of file and in write mode */
137 if (finalseekposition
> eofposition
)
139 if (fdesc
->fcb
->flags
& O_WRITE
)
141 /* Write '0' to fill up to requested size - compatible fseek does not write but allows write */
143 int bytestowrite
= finalseekposition
- eofposition
;
144 int chunkcount
= (bytestowrite
)/128;
145 char zeroarray
[128] = {0};
147 Seek (fh
, 0, OFFSET_END
);
148 for (i
= 0; i
< chunkcount
; i
++)
149 FWrite(fh
, (STRPTR
)zeroarray
, 128, 1);
150 FWrite(fh
, (STRPTR
)zeroarray
, bytestowrite
- (chunkcount
* 128), 1);
155 cnt
= Seek (fh
, finalseekposition
, OFFSET_BEGINNING
);
158 errno
= __stdc_ioerr2errno (IoErr ());
161 /* It's specified that upon success fseek should clear EOF flag
164 stream
->flags
&= ~(__POSIXC_STDIO_EOF
);