1 /* Verify that fseek/ftell combination works for wide chars.
2    Copyright (C) 2012-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <locale.h>
22 #include <errno.h>
23 #include <wchar.h>
24 #include <unistd.h>
25 #include <string.h>
26 
27 #include <support/temp_file.h>
28 
29 static int
do_seek_end(FILE * fp)30 do_seek_end (FILE *fp)
31 {
32   long save;
33 
34   if (fputws (L"abc\n", fp) == -1)
35     {
36       printf ("do_seek_end: fputws: %s\n", strerror (errno));
37       return 1;
38     }
39 
40   save = ftell (fp);
41   rewind (fp);
42 
43   if (fseek (fp, 0, SEEK_END) == -1)
44     {
45       printf ("do_seek_end: fseek: %s\n", strerror (errno));
46       return 1;
47     }
48 
49   if (save != ftell (fp))
50     {
51       printf ("save = %ld, ftell = %ld\n", save, ftell (fp));
52       return 1;
53     }
54 
55   return 0;
56 }
57 
58 int
do_seek_set(FILE * fp)59 do_seek_set (FILE *fp)
60 {
61   long save1, save2;
62 
63   if (fputws (L"ゅう\n", fp) == -1)
64     {
65       printf ("seek_set: fputws(1): %s\n", strerror (errno));
66       return 1;
67     }
68 
69   save1 = ftell (fp);
70 
71   if (fputws (L"ゅう\n", fp) == -1)
72     {
73       printf ("seek_set: fputws(2): %s\n", strerror (errno));
74       return 1;
75     }
76 
77   save2 = ftell (fp);
78 
79   if (fputws (L"ゅう\n", fp) == -1)
80     {
81       printf ("seek_set: fputws(3): %s\n", strerror (errno));
82       return 1;
83     }
84 
85   if (fseek (fp, save1, SEEK_SET) == -1)
86     {
87       printf ("seek_set: fseek(1): %s\n", strerror (errno));
88       return 1;
89     }
90 
91   if (save1 != ftell (fp))
92     {
93       printf ("save1 = %ld, ftell = %ld\n", save1, ftell (fp));
94       return 1;
95     }
96 
97   if (fseek (fp, save2, SEEK_SET) == -1)
98     {
99       printf ("seek_set: fseek(2): %s\n", strerror (errno));
100       return 1;
101     }
102 
103   if (save2 != ftell (fp))
104     {
105       printf ("save2 = %ld, ftell = %ld\n", save2, ftell (fp));
106       return 1;
107     }
108 
109   return 0;
110 }
111 
112 static int
do_test(void)113 do_test (void)
114 {
115   if (setlocale (LC_ALL, "ja_JP.UTF-8") == NULL)
116     {
117       printf ("Cannot set ja_JP.UTF-8 locale.\n");
118       exit (1);
119     }
120 
121   /* Retain messages in English.  */
122   if (setlocale (LC_MESSAGES, "en_US.ISO-8859-1") == NULL)
123     {
124       printf ("Cannot set LC_MESSAGES to en_US.ISO-8859-1 locale.\n");
125       exit (1);
126     }
127 
128   int ret = 0;
129   char *filename;
130   int fd = create_temp_file ("tst-fseek.out", &filename);
131 
132   if (fd == -1)
133     return 1;
134 
135   FILE *fp = fdopen (fd, "w+");
136   if (fp == NULL)
137     {
138       printf ("seek_set: fopen: %s\n", strerror (errno));
139       close (fd);
140       return 1;
141     }
142 
143   if (do_seek_set (fp))
144     {
145       printf ("SEEK_SET test failed\n");
146       ret = 1;
147     }
148 
149   /* Reopen the file.  */
150   fclose (fp);
151   fp = fopen (filename, "w+");
152   if (fp == NULL)
153     {
154       printf ("seek_end: fopen: %s\n", strerror (errno));
155       return 1;
156     }
157 
158   if (do_seek_end (fp))
159     {
160       printf ("SEEK_END test failed\n");
161       ret = 1;
162     }
163 
164   fclose (fp);
165 
166   return ret;
167 }
168 
169 #include <support/test-driver.c>
170