update for HEAD-2003091401
[reactos.git] / lib / msvcrt / stdio / fseek.c
1 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
3 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
4
5 #include <msvcrt/stdio.h>
6 #include <msvcrt/errno.h>
7 #include <msvcrt/fcntl.h>
8 #include <msvcrt/io.h>
9 #include <msvcrt/internal/file.h>
10
11
12 /*
13  * @implemented
14  */
15 int fseek(FILE *f, long offset, int ptrname)
16 {
17   long p = -1;                  /* can't happen? */
18   if ( f == NULL ) {
19         __set_errno (EINVAL);
20        return -1;
21   }
22   
23   f->_flag &= ~_IOEOF;
24   if (!OPEN4WRITING(f))
25   {
26     if (f->_base && !(f->_flag & _IONBF))
27     {
28       p = ftell(f);
29       if (ptrname == SEEK_CUR)
30       {
31         offset += p;
32         ptrname = SEEK_SET;
33       }
34       /* check if the target position is in the buffer and
35         optimize seek by moving inside the buffer */
36       if (ptrname == SEEK_SET && (f->_flag & (_IOUNGETC|_IOREAD|_IOWRT )) == 0
37       && p-offset <= f->_ptr-f->_base && offset-p <= f->_cnt)
38       {
39         f->_ptr+=offset-p;
40         f->_cnt+=p-offset;
41         return 0;
42       }
43     }
44
45     p = lseek(fileno(f), offset, ptrname);
46     f->_cnt = 0;
47     f->_ptr = f->_base;
48     f->_flag &= ~_IOUNGETC;
49   }
50   else 
51   {
52     p = fflush(f);
53     return lseek(fileno(f), offset, ptrname) == -1 || p == EOF ?
54       -1 : 0;
55   }
56   return p==-1 ? -1 : 0;
57 }