chiark / gitweb /
01d1d266fc803ccd295d996b7b3d25cede072b0a
[inn-innduct.git] / fseeko.c
1 /*  $Id: fseeko.c 3680 2000-07-29 22:54:52Z rra $
2 **
3 **  Replacement for a missing fseeko.
4 **
5 **  fseeko is a version of fseek that takes an off_t instead of a long.  For
6 **  large file support (and because it's a more logical interface), INN uses
7 **  fseeko unconditionally; if fseeko isn't provided by a platform but
8 **  fpos_t is compatible with off_t (as in BSDI), define it in terms of
9 **  fsetpos.  Otherwise, just call fseek (which won't work for files over
10 **  2GB).
11 */
12
13 #include "config.h"
14 #include "clibrary.h"
15 #include <errno.h>
16
17 #if HAVE_LARGE_FPOS_T
18
19 int
20 fseeko(FILE *stream, off_t pos, int whence)
21 {
22     fpos_t fpos;
23
24     switch (whence) {
25     case SEEK_SET:
26         fpos = pos;
27         return fsetpos(stream, &fpos);
28
29     case SEEK_END:
30         if (fseek(stream, 0, SEEK_END) < 0)
31             return -1;
32         if (pos == 0)
33             return 0;
34         /* Fall through. */
35
36     case SEEK_CUR:
37         if (fgetpos(stream, &fpos) < 0)
38             return -1;
39         fpos += pos;
40         return fsetpos(stream, &fpos);
41
42     default:
43         errno = EINVAL;
44         return -1;
45     }
46 }
47
48 #else /* !HAVE_LARGE_FPOS_T */
49
50 int
51 fseeko(FILE *stream, off_t pos, int whence)
52 {
53     return fseek(stream, (long) pos, whence);
54 }
55
56 #endif /* !HAVE_LARGE_FPOS_T */