This source file includes following definitions.
- freadptrinc
- freadseek
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <config.h>
18
19
20 #include "freadseek.h"
21
22 #include <stdlib.h>
23 #include <unistd.h>
24
25 #include "freadahead.h"
26 #include "freadptr.h"
27
28 #include "stdio-impl.h"
29
30
31
32
33 static void
34 freadptrinc (FILE *fp, size_t increment)
35 {
36
37 #if HAVE___FREADPTRINC
38 __freadptrinc (fp, increment);
39 #elif defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
40
41 fp->_IO_read_ptr += increment;
42 #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
43
44 fp_->_p += increment;
45 fp_->_r -= increment;
46 #elif defined __EMX__
47 fp->_ptr += increment;
48 fp->_rcount -= increment;
49 #elif defined __minix
50 fp_->_ptr += increment;
51 fp_->_count -= increment;
52 #elif defined _IOERR
53 fp_->_ptr += increment;
54 fp_->_cnt -= increment;
55 #elif defined __UCLIBC__
56 # ifdef __STDIO_BUFFERS
57 fp->__bufpos += increment;
58 # else
59 abort ();
60 # endif
61 #elif defined __QNX__
62 fp->_Next += increment;
63 #elif defined __MINT__
64 fp->__bufp += increment;
65 #elif defined EPLAN9
66 fp->rp += increment;
67 #elif defined SLOW_BUT_NO_HACKS
68 #else
69 #error "Please port gnulib freadseek.c to your platform! Look at the definition of getc, getc_unlocked on your system, then report this to bug-gnulib."
70 #endif
71 }
72
73 int
74 freadseek (FILE *fp, size_t offset)
75 {
76 size_t total_buffered;
77 int fd;
78
79 if (offset == 0)
80 return 0;
81
82
83
84 total_buffered = freadahead (fp);
85
86
87 while (total_buffered > 0)
88 {
89 size_t buffered;
90
91 if (freadptr (fp, &buffered) != NULL && buffered > 0)
92 {
93 size_t increment = (buffered < offset ? buffered : offset);
94
95 freadptrinc (fp, increment);
96 offset -= increment;
97 if (offset == 0)
98 return 0;
99 total_buffered -= increment;
100 if (total_buffered == 0)
101 break;
102 }
103
104
105 if (fgetc (fp) == EOF)
106 goto eof;
107 offset--;
108 if (offset == 0)
109 return 0;
110 total_buffered--;
111 }
112
113
114 fd = fileno (fp);
115 if (fd >= 0 && lseek (fd, 0, SEEK_CUR) >= 0)
116 {
117
118 return fseeko (fp, offset, SEEK_CUR);
119 }
120 else
121 {
122
123
124 char buf[4096];
125
126 do
127 {
128 size_t count = (sizeof (buf) < offset ? sizeof (buf) : offset);
129 if (fread (buf, 1, count, fp) < count)
130 goto eof;
131 offset -= count;
132 }
133 while (offset > 0);
134
135 return 0;
136 }
137
138 eof:
139
140 if (ferror (fp))
141 return EOF;
142 else
143
144 return 0;
145 }