]>
Commit | Line | Data |
---|---|---|
30a4e827 MT |
1 | diff -pruN glibc-2.12-2-gc4ccff1/libio/Makefile glibc-2.12-2-gc4ccff1.fseek/libio/Makefile |
2 | --- glibc-2.12-2-gc4ccff1/libio/Makefile 2010-05-04 16:57:23.000000000 +0530 | |
3 | +++ glibc-2.12-2-gc4ccff1.fseek/libio/Makefile 2012-09-05 17:28:08.699360413 +0530 | |
4 | @@ -58,7 +58,7 @@ tests = tst_swprintf tst_wprintf tst_sws | |
5 | tst-memstream1 tst-memstream2 \ | |
6 | tst-wmemstream1 tst-wmemstream2 \ | |
7 | bug-memstream1 bug-wmemstream1 \ | |
8 | - tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos | |
9 | + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek | |
10 | test-srcs = test-freopen | |
11 | ||
12 | all: # Make this the default target; it will be defined in Rules. | |
13 | diff -pruN glibc-2.12-2-gc4ccff1/libio/tst-fseek.c glibc-2.12-2-gc4ccff1.fseek/libio/tst-fseek.c | |
14 | --- glibc-2.12-2-gc4ccff1/libio/tst-fseek.c 1970-01-01 05:30:00.000000000 +0530 | |
15 | +++ glibc-2.12-2-gc4ccff1.fseek/libio/tst-fseek.c 2012-09-05 17:27:33.606359692 +0530 | |
16 | @@ -0,0 +1,153 @@ | |
17 | +/* Verify that fseek/ftell combination works for wide chars. | |
18 | + | |
19 | + Copyright (C) 2012 Free Software Foundation, Inc. | |
20 | + This file is part of the GNU C Library. | |
21 | + | |
22 | + The GNU C Library is free software; you can redistribute it and/or | |
23 | + modify it under the terms of the GNU Lesser General Public | |
24 | + License as published by the Free Software Foundation; either | |
25 | + version 2.1 of the License, or (at your option) any later version. | |
26 | + | |
27 | + The GNU C Library is distributed in the hope that it will be useful, | |
28 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
30 | + Lesser General Public License for more details. | |
31 | + | |
32 | + You should have received a copy of the GNU Lesser General Public | |
33 | + License along with the GNU C Library; if not, see | |
34 | + <http://www.gnu.org/licenses/>. */ | |
35 | + | |
36 | +#include <stdio.h> | |
37 | +#include <stdlib.h> | |
38 | +#include <locale.h> | |
39 | +#include <errno.h> | |
40 | +#include <wchar.h> | |
41 | +#include <unistd.h> | |
42 | +#include <string.h> | |
43 | + | |
44 | +/* Defined in test-skeleton.c. */ | |
45 | +static int create_temp_file (const char *base, char **filename); | |
46 | + | |
47 | + | |
48 | +static int | |
49 | +do_seek_end (FILE *fp) | |
50 | +{ | |
51 | + long save; | |
52 | + | |
53 | + if (fp == NULL) | |
54 | + { | |
55 | + printf ("do_seek_end: fopen: %s\n", strerror (errno)); | |
56 | + return 1; | |
57 | + } | |
58 | + | |
59 | + if (fputws (L"abc\n", fp) == -1) | |
60 | + { | |
61 | + printf ("do_seek_end: fputws: %s\n", strerror (errno)); | |
62 | + return 1; | |
63 | + } | |
64 | + | |
65 | + save = ftell (fp); | |
66 | + rewind (fp); | |
67 | + | |
68 | + if (fseek (fp, 0, SEEK_END) == -1) | |
69 | + { | |
70 | + printf ("do_seek_end: fseek: %s\n", strerror (errno)); | |
71 | + return 1; | |
72 | + } | |
73 | + | |
74 | + if (save != ftell (fp)) | |
75 | + { | |
76 | + printf ("save = %ld, ftell = %ld\n", save, ftell (fp)); | |
77 | + return 1; | |
78 | + } | |
79 | + | |
80 | + return 0; | |
81 | +} | |
82 | + | |
83 | +int | |
84 | +do_seek_set (FILE *fp) | |
85 | +{ | |
86 | + long save; | |
87 | + | |
88 | + if (fputws (L"abc\n", fp) == -1) | |
89 | + { | |
90 | + printf ("seek_set: fputws: %s\n", strerror (errno)); | |
91 | + return 1; | |
92 | + } | |
93 | + | |
94 | + save = ftell (fp); | |
95 | + | |
96 | + if (fputws (L"xyz\n", fp) == -1) | |
97 | + { | |
98 | + printf ("seek_set: fputws: %s\n", strerror (errno)); | |
99 | + return 1; | |
100 | + } | |
101 | + | |
102 | + if (fseek (fp, save, SEEK_SET) == -1) | |
103 | + { | |
104 | + printf ("seek_set: fseek: %s\n", strerror (errno)); | |
105 | + return 1; | |
106 | + } | |
107 | + | |
108 | + if (save != ftell (fp)) | |
109 | + { | |
110 | + printf ("save = %ld, ftell = %ld\n", save, ftell (fp)); | |
111 | + return 1; | |
112 | + } | |
113 | + | |
114 | + return 0; | |
115 | +} | |
116 | + | |
117 | +static int | |
118 | +do_test (void) | |
119 | +{ | |
120 | + if (setlocale (LC_ALL, "en_US.utf8") == NULL) | |
121 | + { | |
122 | + printf ("Cannot set en_US.utf8 locale.\n"); | |
123 | + exit (1); | |
124 | + } | |
125 | + | |
126 | + int ret = 0; | |
127 | + char *filename; | |
128 | + int fd = create_temp_file ("tst-fseek.out", &filename); | |
129 | + | |
130 | + if (fd == -1) | |
131 | + return 1; | |
132 | + | |
133 | + FILE *fp = fdopen (fd, "w+"); | |
134 | + if (fp == NULL) | |
135 | + { | |
136 | + printf ("seek_set: fopen: %s\n", strerror (errno)); | |
137 | + close (fd); | |
138 | + return 1; | |
139 | + } | |
140 | + | |
141 | + if (do_seek_set (fp)) | |
142 | + { | |
143 | + printf ("SEEK_SET test failed\n"); | |
144 | + ret = 1; | |
145 | + } | |
146 | + | |
147 | + /* Reopen the file. */ | |
148 | + fclose (fp); | |
149 | + fp = fopen (filename, "w+"); | |
150 | + if (fp == NULL) | |
151 | + { | |
152 | + printf ("seek_end: fopen: %s\n", strerror (errno)); | |
153 | + return 1; | |
154 | + } | |
155 | + | |
156 | + if (do_seek_end (fp)) | |
157 | + { | |
158 | + printf ("SEEK_END test failed\n"); | |
159 | + ret = 1; | |
160 | + } | |
161 | + | |
162 | + fclose (fp); | |
163 | + | |
164 | + return ret; | |
165 | +} | |
166 | + | |
167 | + | |
168 | +#define TEST_FUNCTION do_test () | |
169 | +#include "../test-skeleton.c" | |
170 | diff -pruN glibc-2.12-2-gc4ccff1/libio/wfileops.c glibc-2.12-2-gc4ccff1.fseek/libio/wfileops.c | |
171 | --- glibc-2.12-2-gc4ccff1/libio/wfileops.c 2010-05-04 16:57:23.000000000 +0530 | |
172 | +++ glibc-2.12-2-gc4ccff1.fseek/libio/wfileops.c 2012-09-05 17:27:33.608359685 +0530 | |
173 | @@ -547,6 +547,55 @@ _IO_wfile_sync (fp) | |
174 | } | |
175 | INTDEF(_IO_wfile_sync) | |
176 | ||
177 | +/* Adjust the internal buffer pointers to reflect the state in the external | |
178 | + buffer. The content between fp->_IO_read_base and fp->_IO_read_ptr is | |
179 | + assumed to be converted and available in the range | |
180 | + fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end. */ | |
181 | +static inline int | |
182 | +adjust_wide_data (_IO_FILE *fp, bool do_convert) | |
183 | +{ | |
184 | + struct _IO_codecvt *cv = fp->_codecvt; | |
185 | + | |
186 | + int clen = (*cv->__codecvt_do_encoding) (cv); | |
187 | + | |
188 | + /* Take the easy way out for constant length encodings if we don't need to | |
189 | + convert. */ | |
190 | + if (!do_convert && clen > 0) | |
191 | + { | |
192 | + fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base) | |
193 | + / clen); | |
194 | + goto done; | |
195 | + } | |
196 | + | |
197 | + enum __codecvt_result status; | |
198 | + const char *read_stop = (const char *) fp->_IO_read_base; | |
199 | + do | |
200 | + { | |
201 | + | |
202 | + fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; | |
203 | + status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, | |
204 | + fp->_IO_read_base, fp->_IO_read_ptr, | |
205 | + &read_stop, | |
206 | + fp->_wide_data->_IO_read_base, | |
207 | + fp->_wide_data->_IO_buf_end, | |
208 | + &fp->_wide_data->_IO_read_end); | |
209 | + | |
210 | + /* Should we return EILSEQ? */ | |
211 | + if (__builtin_expect (status == __codecvt_error, 0)) | |
212 | + { | |
213 | + fp->_flags |= _IO_ERR_SEEN; | |
214 | + return -1; | |
215 | + } | |
216 | + } | |
217 | + while (__builtin_expect (status == __codecvt_partial, 0)); | |
218 | + | |
219 | +done: | |
220 | + /* Now seek to the end of the read buffer. */ | |
221 | + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; | |
222 | + | |
223 | + return 0; | |
224 | +} | |
225 | + | |
226 | _IO_off64_t | |
227 | _IO_wfile_seekoff (fp, offset, dir, mode) | |
228 | _IO_FILE *fp; | |
229 | @@ -695,6 +744,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode | |
230 | fp->_wide_data->_IO_buf_base); | |
231 | _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, | |
232 | fp->_wide_data->_IO_buf_base); | |
233 | + | |
234 | + if (adjust_wide_data (fp, false)) | |
235 | + goto dumb; | |
236 | + | |
237 | _IO_mask_flags (fp, 0, _IO_EOF_SEEN); | |
238 | goto resync; | |
239 | } | |
240 | @@ -735,6 +788,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode | |
241 | _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, | |
242 | fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); | |
243 | _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base); | |
244 | + | |
245 | + if (adjust_wide_data (fp, true)) | |
246 | + goto dumb; | |
247 | + | |
248 | fp->_offset = result + count; | |
249 | _IO_mask_flags (fp, 0, _IO_EOF_SEEN); | |
250 | return offset; |