]> granicus.if.org Git - postgresql/blob - src/port/fseeko.c
fflush() FILE buffer to descriptor so stat call gets proper size in fseeko.c.
[postgresql] / src / port / fseeko.c
1 /*-------------------------------------------------------------------------
2  *
3  * fseeko.c
4  *        64-bit versions of fseeko/ftello()
5  *
6  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/port/fseeko.c,v 1.14 2004/03/23 05:26:53 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15
16 /*
17  * We have to use the native defines here because configure hasn't
18  * completed yet.
19  */
20 #if defined(__bsdi__) || defined(__NetBSD__)
21
22 #include "c.h"
23
24 #ifdef bsdi
25 #include <pthread.h>
26 #endif
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <errno.h>
31
32 /*
33  *      On BSD/OS and NetBSD, off_t and fpos_t are the same.  Standards
34  *      say off_t is an arithmetic type, but not necessarily integral,
35  *      while fpos_t might be neither.
36  *
37  *      This is thread-safe on BSD/OS using flockfile/funlockfile.
38  */
39
40 int
41 fseeko(FILE *stream, off_t offset, int whence)
42 {
43         off_t           floc;
44         struct stat filestat;
45
46         switch (whence)
47         {
48                 case SEEK_CUR:
49 #ifdef bsdi
50                         flockfile(stream);
51 #endif
52                         if (fgetpos(stream, &floc) != 0)
53                                 goto failure;
54                         floc += offset;
55                         if (fsetpos(stream, &floc) != 0)
56                                 goto failure;
57 #ifdef bsdi
58                         funlockfile(stream);
59 #endif
60                         return 0;
61                         break;
62                 case SEEK_SET:
63                         if (fsetpos(stream, &offset) != 0)
64                                 return -1;
65                         return 0;
66                         break;
67                 case SEEK_END:
68 #ifdef bsdi
69                         flockfile(stream);
70 #endif
71                         fflush(stream); /* force writes to fd for stat() */
72                         if (fstat(fileno(stream), &filestat) != 0)
73                                 goto failure;
74                         floc = filestat.st_size;
75                         if (fsetpos(stream, &floc) != 0)
76                                 goto failure;
77 #ifdef bsdi
78                         funlockfile(stream);
79 #endif
80                         return 0;
81                         break;
82                 default:
83                         errno = EINVAL;
84                         return -1;
85         }
86
87 failure:
88 #ifdef bsdi
89         funlockfile(stream);
90 #endif
91         return -1;
92 }
93
94
95 off_t
96 ftello(FILE *stream)
97 {
98         off_t           floc;
99
100         if (fgetpos(stream, &floc) != 0)
101                 return -1;
102         return floc;
103 }
104
105 #endif