delint
[AROS.git] / rom / dos / seek.c
blobc4955cd24fddf2cee8c5f6bf617d0916154f5e27
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Change the current read/write position in a file.
6 Lang: english
7 */
8 #include <proto/exec.h>
9 #include "dos_intern.h"
11 /*****************************************************************************
13 NAME */
14 #include <proto/dos.h>
16 AROS_LH3(LONG, Seek,
18 /* SYNOPSIS */
19 AROS_LHA(BPTR, file, D1),
20 AROS_LHA(LONG, position, D2),
21 AROS_LHA(LONG, mode, D3),
23 /* LOCATION */
24 struct DosLibrary *, DOSBase, 11, Dos)
26 /* FUNCTION
27 Changes the current read/write position in a file and/or
28 reads the current position, e.g to get the current position
29 do a Seek(file,0,OFFSET_CURRENT).
31 This function may fail (obviously) on certain devices such
32 as pipes or console handlers.
34 INPUTS
35 file - filehandle
36 position - relative offset in bytes (positive, negative or 0).
37 mode - Where to count from. Either OFFSET_BEGINNING,
38 OFFSET_CURRENT or OFFSET_END.
40 RESULT
41 Absolute position in bytes before the Seek(), -1 if an error
42 happened. IoErr() will give additional information in that case.
44 NOTES
46 EXAMPLE
48 BUGS
50 SEE ALSO
52 INTERNALS
54 *****************************************************************************/
56 AROS_LIBFUNC_INIT
58 /* Get pointer to filehandle. */
59 struct FileHandle *fh = (struct FileHandle *)BADDR(file);
60 LONG offset = 0, ret;
62 if (fh == NULL) {
63 SetIoErr(ERROR_INVALID_LOCK);
64 return -1;
67 /* If the file is in append mode, seeking is not allowed. */
68 if( fh->fh_Flags & FHF_APPEND )
70 return InternalSeek( fh, 0, OFFSET_CURRENT, DOSBase );
73 /* If the file is in write mode flush it. */
74 if( fh->fh_Flags & FHF_WRITE )
76 InternalFlush( fh, DOSBase );
78 else
80 /* Read mode. Adjust the offset so that buffering is
81 taken into account. */
82 if (fh->fh_Pos < fh->fh_End && mode == OFFSET_CURRENT)
83 offset = (LONG)(fh->fh_Pos - fh->fh_End);
86 /* Read mode. Just reinit the buffers. We can't call
87 Flush() in this case as that would end up in
88 recursion. */
89 fh->fh_Pos = fh->fh_End = 0;
92 ret = InternalSeek( fh, position + offset, mode, DOSBase );
93 return (ret == -1) ? -1 : (ret + offset);
95 AROS_LIBFUNC_EXIT
96 } /* Seek */