Imported Upstream version 2.61.0
[platform/upstream/glib.git] / glib / tests / fileutils.c
1 /* Unit tests for gfileutils
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This work is provided "as is"; redistribution and modification
5  * in whole or in part, in any medium, physical or electronic is
6  * permitted without restriction.
7  *
8  * This work is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * In no event shall the authors or contributors be liable for any
13  * direct, indirect, incidental, special, exemplary, or consequential
14  * damages (including, but not limited to, procurement of substitute
15  * goods or services; loss of use, data, or profits; or business
16  * interruption) however caused and on any theory of liability, whether
17  * in contract, strict liability, or tort (including negligence or
18  * otherwise) arising in any way out of the use of this software, even
19  * if advised of the possibility of such damage.
20  */
21
22 #include "config.h"
23 #include <string.h>
24 #include <errno.h>
25
26 /* We are testing some deprecated APIs here */
27 #define GLIB_DISABLE_DEPRECATION_WARNINGS
28
29 #include <glib.h>
30
31 /* Test our stdio wrappers here */
32 #define G_STDIO_NO_WRAP_ON_UNIX
33 #include <glib/gstdio.h>
34
35 #ifdef G_OS_UNIX
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <utime.h>
40 #endif
41 #include <fcntl.h>
42 #ifdef G_OS_WIN32
43 #include <windows.h>
44 #include <sys/utime.h>
45 #include <io.h>
46 #ifndef S_ISDIR
47 #define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
48 #endif
49 #ifndef F_OK
50 #define F_OK 0
51 #endif
52 #endif
53
54 #define S G_DIR_SEPARATOR_S
55
56 static void
57 check_string (gchar *str, const gchar *expected)
58 {
59   g_assert_nonnull (str);
60   g_assert_cmpstr (str, ==, expected);
61   g_free (str);
62 }
63
64 static void
65 test_build_path (void)
66 {
67 /*  check_string (g_build_path ("", NULL), "");*/
68   check_string (g_build_path ("", "", NULL), "");
69   check_string (g_build_path ("", "x", NULL), "x");
70   check_string (g_build_path ("", "x", "y",  NULL), "xy");
71   check_string (g_build_path ("", "x", "y", "z", NULL), "xyz");
72
73 /*  check_string (g_build_path (":", NULL), "");*/
74   check_string (g_build_path (":", ":", NULL), ":");
75   check_string (g_build_path (":", ":x", NULL), ":x");
76   check_string (g_build_path (":", "x:", NULL), "x:");
77   check_string (g_build_path (":", "", "x", NULL), "x");
78   check_string (g_build_path (":", "", ":x", NULL), ":x");
79   check_string (g_build_path (":", ":", "x", NULL), ":x");
80   check_string (g_build_path (":", "::", "x", NULL), "::x");
81   check_string (g_build_path (":", "x", "", NULL), "x");
82   check_string (g_build_path (":", "x:", "", NULL), "x:");
83   check_string (g_build_path (":", "x", ":", NULL), "x:");
84   check_string (g_build_path (":", "x", "::", NULL), "x::");
85   check_string (g_build_path (":", "x", "y",  NULL), "x:y");
86   check_string (g_build_path (":", ":x", "y", NULL), ":x:y");
87   check_string (g_build_path (":", "x", "y:", NULL), "x:y:");
88   check_string (g_build_path (":", ":x:", ":y:", NULL), ":x:y:");
89   check_string (g_build_path (":", ":x::", "::y:", NULL), ":x:y:");
90   check_string (g_build_path (":", "x", "","y",  NULL), "x:y");
91   check_string (g_build_path (":", "x", ":", "y",  NULL), "x:y");
92   check_string (g_build_path (":", "x", "::", "y",  NULL), "x:y");
93   check_string (g_build_path (":", "x", "y", "z", NULL), "x:y:z");
94   check_string (g_build_path (":", ":x:", ":y:", ":z:", NULL), ":x:y:z:");
95   check_string (g_build_path (":", "::x::", "::y::", "::z::", NULL), "::x:y:z::");
96
97 /*  check_string (g_build_path ("::", NULL), "");*/
98   check_string (g_build_path ("::", "::", NULL), "::");
99   check_string (g_build_path ("::", ":::", NULL), ":::");
100   check_string (g_build_path ("::", "::x", NULL), "::x");
101   check_string (g_build_path ("::", "x::", NULL), "x::");
102   check_string (g_build_path ("::", "", "x", NULL), "x");
103   check_string (g_build_path ("::", "", "::x", NULL), "::x");
104   check_string (g_build_path ("::", "::", "x", NULL), "::x");
105   check_string (g_build_path ("::", "::::", "x", NULL), "::::x");
106   check_string (g_build_path ("::", "x", "", NULL), "x");
107   check_string (g_build_path ("::", "x::", "", NULL), "x::");
108   check_string (g_build_path ("::", "x", "::", NULL), "x::");
109
110   /* This following is weird, but keeps the definition simple */
111   check_string (g_build_path ("::", "x", ":::", NULL), "x:::::");
112   check_string (g_build_path ("::", "x", "::::", NULL), "x::::");
113   check_string (g_build_path ("::", "x", "y",  NULL), "x::y");
114   check_string (g_build_path ("::", "::x", "y", NULL), "::x::y");
115   check_string (g_build_path ("::", "x", "y::", NULL), "x::y::");
116   check_string (g_build_path ("::", "::x::", "::y::", NULL), "::x::y::");
117   check_string (g_build_path ("::", "::x:::", ":::y::", NULL), "::x::::y::");
118   check_string (g_build_path ("::", "::x::::", "::::y::", NULL), "::x::y::");
119   check_string (g_build_path ("::", "x", "", "y",  NULL), "x::y");
120   check_string (g_build_path ("::", "x", "::", "y",  NULL), "x::y");
121   check_string (g_build_path ("::", "x", "::::", "y",  NULL), "x::y");
122   check_string (g_build_path ("::", "x", "y", "z", NULL), "x::y::z");
123   check_string (g_build_path ("::", "::x::", "::y::", "::z::", NULL), "::x::y::z::");
124   check_string (g_build_path ("::", ":::x:::", ":::y:::", ":::z:::", NULL), ":::x::::y::::z:::");
125   check_string (g_build_path ("::", "::::x::::", "::::y::::", "::::z::::", NULL), "::::x::y::z::::");
126 }
127
128 static void
129 test_build_pathv (void)
130 {
131   gchar *args[10];
132
133   g_assert_null (g_build_pathv ("", NULL));
134   args[0] = NULL;
135   check_string (g_build_pathv ("", args), "");
136   args[0] = ""; args[1] = NULL;
137   check_string (g_build_pathv ("", args), "");
138   args[0] = "x"; args[1] = NULL;
139   check_string (g_build_pathv ("", args), "x");
140   args[0] = "x"; args[1] = "y"; args[2] = NULL;
141   check_string (g_build_pathv ("", args), "xy");
142   args[0] = "x"; args[1] = "y"; args[2] = "z", args[3] = NULL;
143   check_string (g_build_pathv ("", args), "xyz");
144
145   args[0] = NULL;
146   check_string (g_build_pathv (":", args), "");
147   args[0] = ":"; args[1] = NULL;
148   check_string (g_build_pathv (":", args), ":");
149   args[0] = ":x"; args[1] = NULL;
150   check_string (g_build_pathv (":", args), ":x");
151   args[0] = "x:"; args[1] = NULL;
152   check_string (g_build_pathv (":", args), "x:");
153   args[0] = ""; args[1] = "x"; args[2] = NULL;
154   check_string (g_build_pathv (":", args), "x");
155   args[0] = ""; args[1] = ":x"; args[2] = NULL;
156   check_string (g_build_pathv (":", args), ":x");
157   args[0] = ":"; args[1] = "x"; args[2] = NULL;
158   check_string (g_build_pathv (":", args), ":x");
159   args[0] = "::"; args[1] = "x"; args[2] = NULL;
160   check_string (g_build_pathv (":", args), "::x");
161   args[0] = "x"; args[1] = ""; args[2] = NULL;
162   check_string (g_build_pathv (":", args), "x");
163   args[0] = "x:"; args[1] = ""; args[2] = NULL;
164   check_string (g_build_pathv (":", args), "x:");
165   args[0] = "x"; args[1] = ":"; args[2] = NULL;
166   check_string (g_build_pathv (":", args), "x:");
167   args[0] = "x"; args[1] = "::"; args[2] = NULL;
168   check_string (g_build_pathv (":", args), "x::");
169   args[0] = "x"; args[1] = "y"; args[2] = NULL;
170   check_string (g_build_pathv (":", args), "x:y");
171   args[0] = ":x"; args[1] = "y"; args[2] = NULL;
172   check_string (g_build_pathv (":", args), ":x:y");
173   args[0] = "x"; args[1] = "y:"; args[2] = NULL;
174   check_string (g_build_pathv (":", args), "x:y:");
175   args[0] = ":x:"; args[1] = ":y:"; args[2] = NULL;
176   check_string (g_build_pathv (":", args), ":x:y:");
177   args[0] = ":x::"; args[1] = "::y:"; args[2] = NULL;
178   check_string (g_build_pathv (":", args), ":x:y:");
179   args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
180   check_string (g_build_pathv (":", args), "x:y");
181   args[0] = "x"; args[1] = ":"; args[2] = "y"; args[3] = NULL;
182   check_string (g_build_pathv (":", args), "x:y");
183   args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL;
184   check_string (g_build_pathv (":", args), "x:y");
185   args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
186   check_string (g_build_pathv (":", args), "x:y:z");
187   args[0] = ":x:"; args[1] = ":y:"; args[2] = ":z:"; args[3] = NULL;
188   check_string (g_build_pathv (":", args), ":x:y:z:");
189   args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL;
190   check_string (g_build_pathv (":", args), "::x:y:z::");
191
192   args[0] = NULL;
193   check_string (g_build_pathv ("::", args), "");
194   args[0] = "::"; args[1] = NULL;
195   check_string (g_build_pathv ("::", args), "::");
196   args[0] = ":::"; args[1] = NULL;
197   check_string (g_build_pathv ("::", args), ":::");
198   args[0] = "::x"; args[1] = NULL;
199   check_string (g_build_pathv ("::", args), "::x");
200   args[0] = "x::"; args[1] = NULL;
201   check_string (g_build_pathv ("::", args), "x::");
202   args[0] = ""; args[1] = "x"; args[2] = NULL;
203   check_string (g_build_pathv ("::", args), "x");
204   args[0] = ""; args[1] = "::x"; args[2] = NULL;
205   check_string (g_build_pathv ("::", args), "::x");
206   args[0] = "::"; args[1] = "x"; args[2] = NULL;
207   check_string (g_build_pathv ("::", args), "::x");
208   args[0] = "::::"; args[1] = "x"; args[2] = NULL;
209   check_string (g_build_pathv ("::", args), "::::x");
210   args[0] = "x"; args[1] = ""; args[2] = NULL;
211   check_string (g_build_pathv ("::", args), "x");
212   args[0] = "x::"; args[1] = ""; args[2] = NULL;
213   check_string (g_build_pathv ("::", args), "x::");
214   args[0] = "x"; args[1] = "::"; args[2] = NULL;
215   check_string (g_build_pathv ("::", args), "x::");
216   /* This following is weird, but keeps the definition simple */
217   args[0] = "x"; args[1] = ":::"; args[2] = NULL;
218   check_string (g_build_pathv ("::", args), "x:::::");
219   args[0] = "x"; args[1] = "::::"; args[2] = NULL;
220   check_string (g_build_pathv ("::", args), "x::::");
221   args[0] = "x"; args[1] = "y"; args[2] = NULL;
222   check_string (g_build_pathv ("::", args), "x::y");
223   args[0] = "::x"; args[1] = "y"; args[2] = NULL;
224   check_string (g_build_pathv ("::", args), "::x::y");
225   args[0] = "x"; args[1] = "y::"; args[2] = NULL;
226   check_string (g_build_pathv ("::", args), "x::y::");
227   args[0] = "::x::"; args[1] = "::y::"; args[2] = NULL;
228   check_string (g_build_pathv ("::", args), "::x::y::");
229   args[0] = "::x:::"; args[1] = ":::y::"; args[2] = NULL;
230   check_string (g_build_pathv ("::", args), "::x::::y::");
231   args[0] = "::x::::"; args[1] = "::::y::"; args[2] = NULL;
232   check_string (g_build_pathv ("::", args), "::x::y::");
233   args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
234   check_string (g_build_pathv ("::", args), "x::y");
235   args[0] = "x"; args[1] = "::"; args[2] = "y"; args[3] = NULL;
236   check_string (g_build_pathv ("::", args), "x::y");
237   args[0] = "x"; args[1] = "::::"; args[2] = "y"; args[3] = NULL;
238   check_string (g_build_pathv ("::", args), "x::y");
239   args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
240   check_string (g_build_pathv ("::", args), "x::y::z");
241   args[0] = "::x::"; args[1] = "::y::"; args[2] = "::z::"; args[3] = NULL;
242   check_string (g_build_pathv ("::", args), "::x::y::z::");
243   args[0] = ":::x:::"; args[1] = ":::y:::"; args[2] = ":::z:::"; args[3] = NULL;
244   check_string (g_build_pathv ("::", args), ":::x::::y::::z:::");
245   args[0] = "::::x::::"; args[1] = "::::y::::"; args[2] = "::::z::::"; args[3] = NULL;
246   check_string (g_build_pathv ("::", args), "::::x::y::z::::");
247 }
248
249 static void
250 test_build_filename (void)
251 {
252 /*  check_string (g_build_filename (NULL), "");*/
253   check_string (g_build_filename (S, NULL), S);
254   check_string (g_build_filename (S"x", NULL), S"x");
255   check_string (g_build_filename ("x"S, NULL), "x"S);
256   check_string (g_build_filename ("", "x", NULL), "x");
257   check_string (g_build_filename ("", S"x", NULL), S"x");
258   check_string (g_build_filename (S, "x", NULL), S"x");
259   check_string (g_build_filename (S S, "x", NULL), S S"x");
260   check_string (g_build_filename ("x", "", NULL), "x");
261   check_string (g_build_filename ("x"S, "", NULL), "x"S);
262   check_string (g_build_filename ("x", S, NULL), "x"S);
263   check_string (g_build_filename ("x", S S, NULL), "x"S S);
264   check_string (g_build_filename ("x", "y",  NULL), "x"S"y");
265   check_string (g_build_filename (S"x", "y", NULL), S"x"S"y");
266   check_string (g_build_filename ("x", "y"S, NULL), "x"S"y"S);
267   check_string (g_build_filename (S"x"S, S"y"S, NULL), S"x"S"y"S);
268   check_string (g_build_filename (S"x"S S, S S"y"S, NULL), S"x"S"y"S);
269   check_string (g_build_filename ("x", "", "y",  NULL), "x"S"y");
270   check_string (g_build_filename ("x", S, "y",  NULL), "x"S"y");
271   check_string (g_build_filename ("x", S S, "y",  NULL), "x"S"y");
272   check_string (g_build_filename ("x", "y", "z", NULL), "x"S"y"S"z");
273   check_string (g_build_filename (S"x"S, S"y"S, S"z"S, NULL), S"x"S"y"S"z"S);
274   check_string (g_build_filename (S S"x"S S, S S"y"S S, S S"z"S S, NULL), S S"x"S"y"S"z"S S);
275
276 #ifdef G_OS_WIN32
277
278   /* Test also using the slash as file name separator */
279 #define Z "/"
280   /* check_string (g_build_filename (NULL), ""); */
281   check_string (g_build_filename (Z, NULL), Z);
282   check_string (g_build_filename (Z"x", NULL), Z"x");
283   check_string (g_build_filename ("x"Z, NULL), "x"Z);
284   check_string (g_build_filename ("", Z"x", NULL), Z"x");
285   check_string (g_build_filename ("", Z"x", NULL), Z"x");
286   check_string (g_build_filename (Z, "x", NULL), Z"x");
287   check_string (g_build_filename (Z Z, "x", NULL), Z Z"x");
288   check_string (g_build_filename (Z S, "x", NULL), Z S"x");
289   check_string (g_build_filename ("x"Z, "", NULL), "x"Z);
290   check_string (g_build_filename ("x"S"y", "z"Z"a", NULL), "x"S"y"S"z"Z"a");
291   check_string (g_build_filename ("x", Z, NULL), "x"Z);
292   check_string (g_build_filename ("x", Z Z, NULL), "x"Z Z);
293   check_string (g_build_filename ("x", S Z, NULL), "x"S Z);
294   check_string (g_build_filename (Z"x", "y", NULL), Z"x"Z"y");
295   check_string (g_build_filename ("x", "y"Z, NULL), "x"Z"y"Z);
296   check_string (g_build_filename (Z"x"Z, Z"y"Z, NULL), Z"x"Z"y"Z);
297   check_string (g_build_filename (Z"x"Z Z, Z Z"y"Z, NULL), Z"x"Z"y"Z);
298   check_string (g_build_filename ("x", Z, "y",  NULL), "x"Z"y");
299   check_string (g_build_filename ("x", Z Z, "y",  NULL), "x"Z"y");
300   check_string (g_build_filename ("x", Z S, "y",  NULL), "x"S"y");
301   check_string (g_build_filename ("x", S Z, "y",  NULL), "x"Z"y");
302   check_string (g_build_filename ("x", Z "y", "z", NULL), "x"Z"y"Z"z");
303   check_string (g_build_filename ("x", S "y", "z", NULL), "x"S"y"S"z");
304   check_string (g_build_filename ("x", S "y", "z", Z, "a", "b", NULL), "x"S"y"S"z"Z"a"Z"b");
305   check_string (g_build_filename (Z"x"Z, Z"y"Z, Z"z"Z, NULL), Z"x"Z"y"Z"z"Z);
306   check_string (g_build_filename (Z Z"x"Z Z, Z Z"y"Z Z, Z Z"z"Z Z, NULL), Z Z"x"Z"y"Z"z"Z Z);
307
308 #undef Z
309
310 #endif /* G_OS_WIN32 */
311
312 }
313
314 static void
315 test_build_filenamev (void)
316 {
317   gchar *args[10];
318
319   args[0] = NULL;
320   check_string (g_build_filenamev (args), "");
321   args[0] = S; args[1] = NULL;
322   check_string (g_build_filenamev (args), S);
323   args[0] = S"x"; args[1] = NULL;
324   check_string (g_build_filenamev (args), S"x");
325   args[0] = "x"S; args[1] = NULL;
326   check_string (g_build_filenamev (args), "x"S);
327   args[0] = ""; args[1] = "x"; args[2] = NULL;
328   check_string (g_build_filenamev (args), "x");
329   args[0] = ""; args[1] = S"x"; args[2] = NULL;
330   check_string (g_build_filenamev (args), S"x");
331   args[0] = S; args[1] = "x"; args[2] = NULL;
332   check_string (g_build_filenamev (args), S"x");
333   args[0] = S S; args[1] = "x"; args[2] = NULL;
334   check_string (g_build_filenamev (args), S S"x");
335   args[0] = "x"; args[1] = ""; args[2] = NULL;
336   check_string (g_build_filenamev (args), "x");
337   args[0] = "x"S; args[1] = ""; args[2] = NULL;
338   check_string (g_build_filenamev (args), "x"S);
339   args[0] = "x"; args[1] = S; args[2] = NULL;
340   check_string (g_build_filenamev (args), "x"S);
341   args[0] = "x"; args[1] = S S; args[2] = NULL;
342   check_string (g_build_filenamev (args), "x"S S);
343   args[0] = "x"; args[1] = "y"; args[2] = NULL;
344   check_string (g_build_filenamev (args), "x"S"y");
345   args[0] = S"x"; args[1] = "y"; args[2] = NULL;
346   check_string (g_build_filenamev (args), S"x"S"y");
347   args[0] = "x"; args[1] = "y"S; args[2] = NULL;
348   check_string (g_build_filenamev (args), "x"S"y"S);
349   args[0] = S"x"S; args[1] = S"y"S; args[2] = NULL;
350   check_string (g_build_filenamev (args), S"x"S"y"S);
351   args[0] = S"x"S S; args[1] = S S"y"S; args[2] = NULL;
352   check_string (g_build_filenamev (args), S"x"S"y"S);
353   args[0] = "x"; args[1] = ""; args[2] = "y"; args[3] = NULL;
354   check_string (g_build_filenamev (args), "x"S"y");
355   args[0] = "x"; args[1] = S; args[2] = "y"; args[3] = NULL;
356   check_string (g_build_filenamev (args), "x"S"y");
357   args[0] = "x"; args[1] = S S; args[2] = "y"; args[3] = NULL;
358   check_string (g_build_filenamev (args), "x"S"y");
359   args[0] = "x"; args[1] = "y"; args[2] = "z"; args[3] = NULL;
360   check_string (g_build_filenamev (args), "x"S"y"S"z");
361   args[0] = S"x"S; args[1] = S"y"S; args[2] = S"z"S; args[3] = NULL;
362   check_string (g_build_filenamev (args), S"x"S"y"S"z"S);
363   args[0] = S S"x"S S; args[1] = S S"y"S S; args[2] = S S"z"S S; args[3] = NULL;
364   check_string (g_build_filenamev (args), S S"x"S"y"S"z"S S);
365
366 #ifdef G_OS_WIN32
367
368   /* Test also using the slash as file name separator */
369 #define Z "/"
370   args[0] = NULL;
371   check_string (g_build_filenamev (args), "");
372   args[0] = Z; args[1] = NULL;
373   check_string (g_build_filenamev (args), Z);
374   args[0] = Z"x"; args[1] = NULL;
375   check_string (g_build_filenamev (args), Z"x");
376   args[0] = "x"Z; args[1] = NULL;
377   check_string (g_build_filenamev (args), "x"Z);
378   args[0] = ""; args[1] = Z"x"; args[2] = NULL;
379   check_string (g_build_filenamev (args), Z"x");
380   args[0] = ""; args[1] = Z"x"; args[2] = NULL;
381   check_string (g_build_filenamev (args), Z"x");
382   args[0] = Z; args[1] = "x"; args[2] = NULL;
383   check_string (g_build_filenamev (args), Z"x");
384   args[0] = Z Z; args[1] = "x"; args[2] = NULL;
385   check_string (g_build_filenamev (args), Z Z"x");
386   args[0] = Z S; args[1] = "x"; args[2] = NULL;
387   check_string (g_build_filenamev (args), Z S"x");
388   args[0] = "x"Z; args[1] = ""; args[2] = NULL;
389   check_string (g_build_filenamev (args), "x"Z);
390   args[0] = "x"S"y"; args[1] = "z"Z"a"; args[2] = NULL;
391   check_string (g_build_filenamev (args), "x"S"y"S"z"Z"a");
392   args[0] = "x"; args[1] = Z; args[2] = NULL;
393   check_string (g_build_filenamev (args), "x"Z);
394   args[0] = "x"; args[1] = Z Z; args[2] = NULL;
395   check_string (g_build_filenamev (args), "x"Z Z);
396   args[0] = "x"; args[1] = S Z; args[2] = NULL;
397   check_string (g_build_filenamev (args), "x"S Z);
398   args[0] = Z"x"; args[1] = "y"; args[2] = NULL;
399   check_string (g_build_filenamev (args), Z"x"Z"y");
400   args[0] = "x"; args[1] = "y"Z; args[2] = NULL;
401   check_string (g_build_filenamev (args), "x"Z"y"Z);
402   args[0] = Z"x"Z; args[1] = Z"y"Z; args[2] = NULL;
403   check_string (g_build_filenamev (args), Z"x"Z"y"Z);
404   args[0] = Z"x"Z Z; args[1] = Z Z"y"Z; args[2] = NULL;
405   check_string (g_build_filenamev (args), Z"x"Z"y"Z);
406   args[0] = "x"; args[1] = Z; args[2] = "y", args[3] = NULL;
407   check_string (g_build_filenamev (args), "x"Z"y");
408   args[0] = "x"; args[1] = Z Z; args[2] = "y", args[3] = NULL;
409   check_string (g_build_filenamev (args), "x"Z"y");
410   args[0] = "x"; args[1] = Z S; args[2] = "y", args[3] = NULL;
411   check_string (g_build_filenamev (args), "x"S"y");
412   args[0] = "x"; args[1] = S Z; args[2] = "y", args[3] = NULL;
413   check_string (g_build_filenamev (args), "x"Z"y");
414   args[0] = "x"; args[1] = Z "y"; args[2] = "z", args[3] = NULL;
415   check_string (g_build_filenamev (args), "x"Z"y"Z"z");
416   args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = NULL;
417   check_string (g_build_filenamev (args), "x"S"y"S"z");
418   args[0] = "x"; args[1] = S "y"; args[2] = "z", args[3] = Z;
419   args[4] = "a"; args[5] = "b"; args[6] = NULL;
420   check_string (g_build_filenamev (args), "x"S"y"S"z"Z"a"Z"b");
421   args[0] = Z"x"Z; args[1] = Z"y"Z; args[2] = Z"z"Z, args[3] = NULL;
422   check_string (g_build_filenamev (args), Z"x"Z"y"Z"z"Z);
423   args[0] = Z Z"x"Z Z; args[1] = Z Z"y"Z Z; args[2] = Z Z"z"Z Z, args[3] = NULL;
424   check_string (g_build_filenamev (args), Z Z"x"Z"y"Z"z"Z Z);
425
426 #undef Z
427
428 #endif /* G_OS_WIN32 */
429 }
430
431 #undef S
432
433 static void
434 test_mkdir_with_parents_1 (const gchar *base)
435 {
436   char *p0 = g_build_filename (base, "fum", NULL);
437   char *p1 = g_build_filename (p0, "tem", NULL);
438   char *p2 = g_build_filename (p1, "zap", NULL);
439   FILE *f;
440
441   g_remove (p2);
442   g_remove (p1);
443   g_remove (p0);
444
445   if (g_file_test (p0, G_FILE_TEST_EXISTS))
446     g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p0);
447
448   if (g_file_test (p1, G_FILE_TEST_EXISTS))
449     g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p1);
450
451   if (g_file_test (p2, G_FILE_TEST_EXISTS))
452     g_error ("failed, %s exists, cannot test g_mkdir_with_parents", p2);
453
454   if (g_mkdir_with_parents (p2, 0777) == -1)
455     {
456       int errsv = errno;
457       g_error ("failed, g_mkdir_with_parents(%s) failed: %s", p2, g_strerror (errsv));
458     }
459
460   if (!g_file_test (p2, G_FILE_TEST_IS_DIR))
461     g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p2);
462
463   if (!g_file_test (p1, G_FILE_TEST_IS_DIR))
464     g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p1);
465
466   if (!g_file_test (p0, G_FILE_TEST_IS_DIR))
467     g_error ("failed, g_mkdir_with_parents(%s) succeeded, but %s is not a directory", p2, p0);
468
469   g_rmdir (p2);
470   if (g_file_test (p2, G_FILE_TEST_EXISTS))
471     g_error ("failed, did g_rmdir(%s), but %s is still there", p2, p2);
472
473   g_rmdir (p1);
474   if (g_file_test (p1, G_FILE_TEST_EXISTS))
475     g_error ("failed, did g_rmdir(%s), but %s is still there", p1, p1);
476
477   f = g_fopen (p1, "w");
478   if (f == NULL)
479     g_error ("failed, couldn't create file %s", p1);
480   fclose (f);
481
482   if (g_mkdir_with_parents (p1, 0666) == 0)
483     g_error ("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file", p1, p1);
484
485   if (g_mkdir_with_parents (p2, 0666) == 0)
486     g_error("failed, g_mkdir_with_parents(%s) succeeded, even if %s is a file", p2, p1);
487
488   g_remove (p2);
489   g_remove (p1);
490   g_remove (p0);
491
492   g_free (p2);
493   g_free (p1);
494   g_free (p0);
495 }
496
497 static void
498 test_mkdir_with_parents (void)
499 {
500   gchar *cwd;
501   if (g_test_verbose())
502     g_printerr ("checking g_mkdir_with_parents() in subdir ./hum/");
503   test_mkdir_with_parents_1 ("hum");
504   g_remove ("hum");
505   if (g_test_verbose())
506     g_printerr ("checking g_mkdir_with_parents() in subdir ./hii///haa/hee/");
507   test_mkdir_with_parents_1 ("hii///haa/hee");
508   g_remove ("hii/haa/hee");
509   g_remove ("hii/haa");
510   g_remove ("hii");
511   cwd = g_get_current_dir ();
512   if (g_test_verbose())
513     g_printerr ("checking g_mkdir_with_parents() in cwd: %s", cwd);
514   test_mkdir_with_parents_1 (cwd);
515   g_free (cwd);
516
517   g_assert_cmpint (g_mkdir_with_parents (NULL, 0), ==, -1);
518   g_assert_cmpint (errno, ==, EINVAL);
519 }
520
521 static void
522 test_format_size_for_display (void)
523 {
524 #ifdef G_OS_WIN32
525   SetThreadLocale (MAKELCID (MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
526 #endif
527   /* nobody called setlocale(), so we should get "C" behaviour... */
528   check_string (g_format_size_for_display (0), "0 bytes");
529   check_string (g_format_size_for_display (1), "1 byte");
530   check_string (g_format_size_for_display (2), "2 bytes");
531   check_string (g_format_size_for_display (1024), "1.0 KB");
532   check_string (g_format_size_for_display (1024 * 1024), "1.0 MB");
533   check_string (g_format_size_for_display (1024 * 1024 * 1024), "1.0 GB");
534   check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024), "1.0 TB");
535   check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024 * 1024), "1.0 PB");
536   check_string (g_format_size_for_display (1024ULL * 1024 * 1024 * 1024 * 1024 * 1024), "1.0 EB");
537
538   check_string (g_format_size (0), "0 bytes");
539   check_string (g_format_size (1), "1 byte");
540   check_string (g_format_size (2), "2 bytes");
541   /* '\302\240' is a no-break space, to keep quantity and unit symbol together at line breaks*/
542   check_string (g_format_size (1000ULL), "1.0\302\240kB");
543   check_string (g_format_size (1000ULL * 1000), "1.0\302\240MB");
544   check_string (g_format_size (1000ULL * 1000 * 1000), "1.0\302\240GB");
545   check_string (g_format_size (1000ULL * 1000 * 1000 * 1000), "1.0\302\240TB");
546   check_string (g_format_size (1000ULL * 1000 * 1000 * 1000 * 1000), "1.0\302\240PB");
547   check_string (g_format_size (1000ULL * 1000 * 1000 * 1000 * 1000 * 1000), "1.0\302\240EB");
548
549   check_string (g_format_size_full (0, G_FORMAT_SIZE_IEC_UNITS), "0 bytes");
550   check_string (g_format_size_full (1, G_FORMAT_SIZE_IEC_UNITS), "1 byte");
551   check_string (g_format_size_full (2, G_FORMAT_SIZE_IEC_UNITS), "2 bytes");
552
553   check_string (g_format_size_full (2048ULL, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240KiB");
554   check_string (g_format_size_full (2048ULL * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240MiB");
555   check_string (g_format_size_full (2048ULL * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240GiB");
556   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240TiB");
557   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240PiB");
558   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240EiB");
559
560   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_IEC_UNITS), "227.4\302\240MiB");
561   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_DEFAULT), "238.5\302\240MB");
562   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_LONG_FORMAT), "238.5\302\240MB (238472938 bytes)");
563
564
565   check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS), "0 bits");
566   check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS), "1 bit");
567   check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS), "2 bits");
568
569   check_string (g_format_size_full (2000ULL, G_FORMAT_SIZE_BITS), "2.0\302\240kb");
570   check_string (g_format_size_full (2000ULL * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Mb");
571   check_string (g_format_size_full (2000ULL * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Gb");
572   check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Tb");
573   check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Pb");
574   check_string (g_format_size_full (2000ULL * 1000 * 1000 * 1000 * 1000 * 1000, G_FORMAT_SIZE_BITS), "2.0\302\240Eb");
575
576   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS), "238.5\302\240Mb");
577   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_LONG_FORMAT), "238.5\302\240Mb (238472938 bits)");
578
579
580   check_string (g_format_size_full (0, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "0 bits");
581   check_string (g_format_size_full (1, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "1 bit");
582   check_string (g_format_size_full (2, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2 bits");
583
584   check_string (g_format_size_full (2048ULL, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Kib");
585   check_string (g_format_size_full (2048ULL * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Mib");
586   check_string (g_format_size_full (2048ULL * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Gib");
587   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Tib");
588   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Pib");
589   check_string (g_format_size_full (2048ULL * 1024 * 1024 * 1024 * 1024 * 1024, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "2.0\302\240Eib");
590
591   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS), "227.4\302\240Mib");
592   check_string (g_format_size_full (238472938, G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS | G_FORMAT_SIZE_LONG_FORMAT), "227.4\302\240Mib (238472938 bits)");
593 }
594
595 static void
596 test_file_errors (void)
597 {
598 #ifdef EEXIST
599   g_assert_cmpint (g_file_error_from_errno (EEXIST), ==, G_FILE_ERROR_EXIST);
600 #endif
601 #ifdef EISDIR
602   g_assert_cmpint (g_file_error_from_errno (EISDIR), ==, G_FILE_ERROR_ISDIR);
603 #endif
604 #ifdef EACCES
605   g_assert_cmpint (g_file_error_from_errno (EACCES), ==, G_FILE_ERROR_ACCES);
606 #endif
607 #ifdef ENAMETOOLONG
608   g_assert_cmpint (g_file_error_from_errno (ENAMETOOLONG), ==, G_FILE_ERROR_NAMETOOLONG);
609 #endif
610 #ifdef ENOENT
611   g_assert_cmpint (g_file_error_from_errno (ENOENT), ==, G_FILE_ERROR_NOENT);
612 #endif
613 #ifdef ENOTDIR
614   g_assert_cmpint (g_file_error_from_errno (ENOTDIR), ==, G_FILE_ERROR_NOTDIR);
615 #endif
616 #ifdef ENXIO
617   g_assert_cmpint (g_file_error_from_errno (ENXIO), ==, G_FILE_ERROR_NXIO);
618 #endif
619 #ifdef ENODEV
620   g_assert_cmpint (g_file_error_from_errno (ENODEV), ==, G_FILE_ERROR_NODEV);
621 #endif
622 #ifdef EROFS
623   g_assert_cmpint (g_file_error_from_errno (EROFS), ==, G_FILE_ERROR_ROFS);
624 #endif
625 #ifdef ETXTBSY
626   g_assert_cmpint (g_file_error_from_errno (ETXTBSY), ==, G_FILE_ERROR_TXTBSY);
627 #endif
628 #ifdef EFAULT
629   g_assert_cmpint (g_file_error_from_errno (EFAULT), ==, G_FILE_ERROR_FAULT);
630 #endif
631 #ifdef ELOOP
632   g_assert_cmpint (g_file_error_from_errno (ELOOP), ==, G_FILE_ERROR_LOOP);
633 #endif
634 #ifdef ENOSPC
635   g_assert_cmpint (g_file_error_from_errno (ENOSPC), ==, G_FILE_ERROR_NOSPC);
636 #endif
637 #ifdef ENOMEM
638   g_assert_cmpint (g_file_error_from_errno (ENOMEM), ==, G_FILE_ERROR_NOMEM);
639 #endif
640 #ifdef EMFILE
641   g_assert_cmpint (g_file_error_from_errno (EMFILE), ==, G_FILE_ERROR_MFILE);
642 #endif
643 #ifdef ENFILE
644   g_assert_cmpint (g_file_error_from_errno (ENFILE), ==, G_FILE_ERROR_NFILE);
645 #endif
646 #ifdef EBADF
647   g_assert_cmpint (g_file_error_from_errno (EBADF), ==, G_FILE_ERROR_BADF);
648 #endif
649 #ifdef EINVAL
650   g_assert_cmpint (g_file_error_from_errno (EINVAL), ==, G_FILE_ERROR_INVAL);
651 #endif
652 #ifdef EPIPE
653   g_assert_cmpint (g_file_error_from_errno (EPIPE), ==, G_FILE_ERROR_PIPE);
654 #endif
655 #ifdef EAGAIN
656   g_assert_cmpint (g_file_error_from_errno (EAGAIN), ==, G_FILE_ERROR_AGAIN);
657 #endif
658 #ifdef EINTR
659   g_assert_cmpint (g_file_error_from_errno (EINTR), ==, G_FILE_ERROR_INTR);
660 #endif
661 #ifdef EIO
662   g_assert_cmpint (g_file_error_from_errno (EIO), ==, G_FILE_ERROR_IO);
663 #endif
664 #ifdef EPERM
665   g_assert_cmpint (g_file_error_from_errno (EPERM), ==, G_FILE_ERROR_PERM);
666 #endif
667 #ifdef ENOSYS
668   g_assert_cmpint (g_file_error_from_errno (ENOSYS), ==, G_FILE_ERROR_NOSYS);
669 #endif
670 }
671
672 static void
673 test_basename (void)
674 {
675   gchar *b;
676
677   b = g_path_get_basename ("");
678   g_assert_cmpstr (b, ==, ".");
679   g_free (b);
680
681   b = g_path_get_basename ("///");
682   g_assert_cmpstr (b, ==, G_DIR_SEPARATOR_S);
683   g_free (b);
684
685   b = g_path_get_basename ("/a/b/c/d");
686   g_assert_cmpstr (b, ==, "d");
687   g_free (b);
688 }
689
690 static void
691 test_dir_make_tmp (void)
692 {
693   gchar *name;
694   GError *error = NULL;
695   gint ret;
696
697   name = g_dir_make_tmp ("testXXXXXXtest", &error);
698   g_assert_no_error (error);
699   g_assert_true (g_file_test (name, G_FILE_TEST_IS_DIR));
700   ret = g_rmdir (name);
701   g_assert_cmpint (ret, ==, 0);
702   g_free (name);
703
704   name = g_dir_make_tmp (NULL, &error);
705   g_assert_no_error (error);
706   g_assert_true (g_file_test (name, G_FILE_TEST_IS_DIR));
707   ret = g_rmdir (name);
708   g_assert_cmpint (ret, ==, 0);
709   g_free (name);
710
711   name = g_dir_make_tmp ("test/XXXXXX", &error);
712   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
713   g_clear_error (&error);
714   g_assert_null (name);
715
716   name = g_dir_make_tmp ("XXXXxX", &error);
717   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
718   g_clear_error (&error);
719   g_assert_null (name);
720 }
721
722 static void
723 test_file_open_tmp (void)
724 {
725   gchar *name = NULL;
726   GError *error = NULL;
727   gint fd;
728
729   fd = g_file_open_tmp ("testXXXXXXtest", &name, &error);
730   g_assert_cmpint (fd, !=, -1);
731   g_assert_no_error (error);
732   g_assert_nonnull (name);
733   unlink (name);
734   g_free (name);
735   close (fd);
736
737   fd = g_file_open_tmp (NULL, &name, &error);
738   g_assert_cmpint (fd, !=, -1);
739   g_assert_no_error (error);
740   g_assert_nonnull (name);
741   g_unlink (name);
742   g_free (name);
743   close (fd);
744
745   name = NULL;
746   fd = g_file_open_tmp ("test/XXXXXX", &name, &error);
747   g_assert_cmpint (fd, ==, -1);
748   g_assert_null (name);
749   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
750   g_clear_error (&error);
751
752   fd = g_file_open_tmp ("XXXXxX", &name, &error);
753   g_assert_cmpint (fd, ==, -1);
754   g_assert_null (name);
755   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED);
756   g_clear_error (&error);
757 }
758
759 static void
760 test_mkstemp (void)
761 {
762   gchar *name;
763   gint fd;
764
765   name = g_strdup ("testXXXXXXtest"),
766   fd = g_mkstemp (name);
767   g_assert_cmpint (fd, !=, -1);
768   g_assert_null (strstr (name, "XXXXXX"));
769   unlink (name);
770   close (fd);
771   g_free (name);
772
773   name = g_strdup ("testYYYYYYtest"),
774   fd = g_mkstemp (name);
775   g_assert_cmpint (fd, ==, -1);
776   g_free (name);
777 }
778
779 static void
780 test_mkdtemp (void)
781 {
782   gchar *name;
783   gchar *ret;
784
785   name = g_strdup ("testXXXXXXtest"),
786   ret = g_mkdtemp (name);
787   g_assert (ret == name);
788   g_assert_null (strstr (name, "XXXXXX"));
789   g_rmdir (name);
790   g_free (name);
791
792   name = g_strdup ("testYYYYYYtest"),
793   ret = g_mkdtemp (name);
794   g_assert_null (ret);
795   g_free (name);
796 }
797
798 static void
799 test_set_contents (void)
800 {
801   GError *error = NULL;
802   gint fd;
803   gchar *name;
804   gchar *buf;
805   gsize len;
806   gboolean ret;
807
808   fd = g_file_open_tmp (NULL, &name, &error);
809   g_assert_no_error (error);
810   write (fd, "a", 1);
811   close (fd);
812
813   ret = g_file_get_contents (name, &buf, &len, &error);
814   g_assert_true (ret);
815   g_assert_no_error (error);
816   g_assert_cmpstr (buf, ==, "a");
817   g_free (buf);
818
819   ret = g_file_set_contents (name, "b", 1, &error);
820   g_assert_true (ret);
821   g_assert_no_error (error);
822
823   ret = g_file_get_contents (name, &buf, &len, &error);
824   g_assert_true (ret);
825   g_assert_no_error (error);
826   g_assert_cmpstr (buf, ==, "b");
827   g_free (buf);
828
829   g_remove (name);
830   g_free (name);
831 }
832
833 static void
834 test_read_link (void)
835 {
836 #ifdef HAVE_READLINK
837 #ifdef G_OS_UNIX
838   int ret;
839   const gchar *oldpath;
840   gchar *cwd;
841   gchar *newpath;
842   gchar *badpath;
843   gchar *path;
844   GError *error = NULL;
845
846   cwd = g_get_current_dir ();
847
848   oldpath = g_test_get_filename (G_TEST_DIST, "4096-random-bytes", NULL);
849   newpath = g_build_filename (cwd, "page-of-junk", NULL);
850   badpath = g_build_filename (cwd, "4097-random-bytes", NULL);
851   remove (newpath);
852   ret = symlink (oldpath, newpath);
853   g_assert_cmpint (ret, ==, 0);
854   path = g_file_read_link (newpath, &error);
855   g_assert_no_error (error);
856   g_assert_cmpstr (path, ==, oldpath);
857   g_free (path);
858
859   remove (newpath);
860   ret = symlink (badpath, newpath);
861   g_assert_cmpint (ret, ==, 0);
862   path = g_file_read_link (newpath, &error);
863   g_assert_no_error (error);
864   g_assert_cmpstr (path, ==, badpath);
865   g_free (path);
866
867   path = g_file_read_link (oldpath, &error);
868   g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL);
869   g_assert_null (path);
870   g_error_free (error);
871
872   remove (newpath);
873   g_free (cwd);
874   g_free (newpath);
875   g_free (badpath);
876
877 #endif
878 #else
879   g_test_skip ("Symbolic links not supported");
880 #endif
881 }
882
883 static void
884 test_stdio_wrappers (void)
885 {
886   GStatBuf buf;
887   gchar *cwd, *path;
888   gint ret;
889   struct utimbuf ut;
890   GError *error = NULL;
891   GStatBuf path_statbuf, cwd_statbuf;
892   time_t now;
893
894   /* The permissions tests here don’t work when running as root. */
895 #ifdef G_OS_UNIX
896   if (getuid () == 0 || geteuid () == 0)
897     {
898       g_test_skip ("File permissions tests cannot be run as root");
899       return;
900     }
901 #endif
902
903   g_remove ("mkdir-test/test-create");
904   ret = g_rmdir ("mkdir-test");
905   g_assert (ret == 0 || errno == ENOENT);
906
907   ret = g_stat ("mkdir-test", &buf);
908   g_assert_cmpint (ret, ==, -1);
909   ret = g_mkdir ("mkdir-test", 0666);
910   g_assert_cmpint (ret, ==, 0);
911   ret = g_stat ("mkdir-test", &buf);
912   g_assert_cmpint (ret, ==, 0);
913   g_assert_cmpint (S_ISDIR (buf.st_mode), !=, 0);
914
915   cwd = g_get_current_dir ();
916   path = g_build_filename (cwd, "mkdir-test", NULL);
917   g_free (cwd);
918 #ifndef G_OS_WIN32
919   /* 0666 on directories means nothing to Windows, it only obeys ACLs */
920   ret = g_chdir (path);
921   g_assert_cmpint (errno, ==, EACCES);
922   g_assert_cmpint (ret, ==, -1);
923 #endif
924   ret = g_chmod (path, 0777);
925   g_assert_cmpint (ret, ==, 0);
926   ret = g_chdir (path);
927   g_assert_cmpint (ret, ==, 0);
928   cwd = g_get_current_dir ();
929   /* We essentially want to check that cwd == path, but we can’t compare the
930    * paths directly since the tests might be running under a symlink (for
931    * example, /tmp is sometimes a symlink). Compare the inode numbers instead. */
932   g_assert_cmpint (g_stat (cwd, &cwd_statbuf), ==, 0);
933   g_assert_cmpint (g_stat (path, &path_statbuf), ==, 0);
934   g_assert_true (cwd_statbuf.st_dev == path_statbuf.st_dev &&
935                  cwd_statbuf.st_ino == path_statbuf.st_ino);
936   g_free (cwd);
937   g_free (path);
938
939   ret = g_creat ("test-creat", 0555);
940   g_close (ret, &error);
941   g_assert_no_error (error);
942
943   ret = g_access ("test-creat", F_OK);
944   g_assert_cmpint (ret, ==, 0);
945
946   ret = g_rename ("test-creat", "test-create");
947   g_assert_cmpint (ret, ==, 0);
948
949   ret = g_open ("test-create", O_RDONLY, 0666);
950   g_close (ret, &error);
951   g_assert_no_error (error);
952
953 #ifdef G_OS_WIN32
954   /* On Windows the 5 permission bit results in a read-only file
955    * that cannot be modified in any way (attribute changes included).
956    * Remove the read-only attribute via chmod().
957    */
958   ret = g_chmod ("test-create", 0666);
959   g_assert_cmpint (ret, ==, 0);
960 #endif
961
962   now = time (NULL);
963
964   ut.actime = ut.modtime = now;
965   ret = g_utime ("test-create", &ut);
966   g_assert_cmpint (ret, ==, 0);
967
968   ret = g_lstat ("test-create", &buf);
969   g_assert_cmpint (ret, ==, 0);
970   g_assert_cmpint (buf.st_atime, ==, now);
971   g_assert_cmpint (buf.st_mtime, ==, now);
972
973   g_chdir ("..");
974   g_remove ("mkdir-test/test-create");
975   g_rmdir ("mkdir-test");
976 }
977
978 /* Win32 does not support "wb+", but g_fopen() should automatically
979  * translate this mode to its alias "w+b".
980  * Also check various other file open modes for correct support accross
981  * platforms.
982  * See: https://gitlab.gnome.org/GNOME/glib/merge_requests/119
983  */
984 static void
985 test_fopen_modes (void)
986 {
987   char        *path = g_build_filename ("temp-fopen", NULL);
988   gsize        i;
989   const gchar *modes[] =
990     {
991       "w",
992       "r",
993       "a",
994       "w+",
995       "r+",
996       "a+",
997       "wb",
998       "rb",
999       "ab",
1000       "w+b",
1001       "r+b",
1002       "a+b",
1003       "wb+",
1004       "rb+",
1005       "ab+"
1006     };
1007
1008   g_test_bug ("119");
1009
1010   if (g_file_test (path, G_FILE_TEST_EXISTS))
1011     g_error ("failed, %s exists, cannot test g_fopen()", path);
1012
1013   for (i = 0; i < G_N_ELEMENTS (modes); i++)
1014     {
1015       FILE *f;
1016
1017       g_test_message ("Testing fopen() mode '%s'", modes[i]);
1018
1019       f = g_fopen (path, modes[i]);
1020       g_assert_nonnull (f);
1021       fclose (f);
1022     }
1023
1024   g_remove (path);
1025   g_free (path);
1026 }
1027
1028 #ifdef G_OS_WIN32
1029 #include "../gstdio-private.c"
1030
1031 static int
1032 g_wcscmp0 (const gunichar2 *str1,
1033            const gunichar2 *str2)
1034 {
1035   if (!str1)
1036     return -(str1 != str2);
1037   if (!str2)
1038     return str1 != str2;
1039   return wcscmp (str1, str2);
1040 }
1041
1042 #define g_assert_cmpwcs(s1, cmp, s2, s1u8, s2u8) \
1043 G_STMT_START { \
1044   const gunichar2 *__s1 = (s1), *__s2 = (s2); \
1045   if (g_wcscmp0 (__s1, __s2) cmp 0) ; else \
1046     g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
1047                                 #s1u8 " " #cmp " " #s2u8, s1u8, #cmp, s2u8); \
1048 } G_STMT_END
1049
1050 static void
1051 test_win32_pathstrip (void)
1052 {
1053   gunichar2 *buf;
1054   gsize i;
1055 #define IDENTITY_TEST(x) { x, x, FALSE }
1056   struct
1057   {
1058     gunichar2 *in;
1059     gunichar2 *out;
1060     gboolean   result;
1061   } testcases[] = {
1062     IDENTITY_TEST (L"\\\\?\\V"),
1063     IDENTITY_TEST (L"\\\\?\\Vo"),
1064     IDENTITY_TEST (L"\\\\?\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"),
1065     IDENTITY_TEST (L"\\??\\V"),
1066     IDENTITY_TEST (L"\\??\\Vo"),
1067     IDENTITY_TEST (L"\\??\\Volume{0700f3d3-6d24-11e3-8b2f-806e6f6e6963}\\"),
1068     IDENTITY_TEST (L"\\\\?\\\x0441:\\"),
1069     IDENTITY_TEST (L"\\??\\\x0441:\\"),
1070     IDENTITY_TEST (L"a:\\"),
1071     IDENTITY_TEST (L"a:\\b\\c"),
1072     IDENTITY_TEST (L"x"),
1073 #undef IDENTITY_TEST
1074     {
1075       L"\\\\?\\c:\\",
1076              L"c:\\",
1077       TRUE,
1078     },
1079     {
1080       L"\\\\?\\C:\\",
1081              L"C:\\",
1082       TRUE,
1083     },
1084     {
1085       L"\\\\?\\c:\\",
1086              L"c:\\",
1087       TRUE,
1088     },
1089     {
1090       L"\\\\?\\C:\\",
1091              L"C:\\",
1092       TRUE,
1093     },
1094     {
1095       L"\\\\?\\C:\\",
1096              L"C:\\",
1097       TRUE,
1098     },
1099     { 0, }
1100   };
1101
1102   for (i = 0; testcases[i].in; i++)
1103     {
1104       gsize str_len = wcslen (testcases[i].in) + 1;
1105       gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL);
1106       gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL);
1107
1108       g_assert_nonnull (in_u8);
1109       g_assert_nonnull (out_u8);
1110
1111       buf = g_new0 (gunichar2, str_len);
1112       memcpy (buf, testcases[i].in, str_len * sizeof (gunichar2));
1113       _g_win32_strip_extended_ntobjm_prefix (buf, &str_len);
1114       g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8);
1115       g_free (buf);
1116       g_free (in_u8);
1117       g_free (out_u8);
1118     }
1119   /* Check for correct behaviour on non-NUL-terminated strings */
1120   for (i = 0; testcases[i].in; i++)
1121     {
1122       gsize str_len = wcslen (testcases[i].in) + 1;
1123       wchar_t old_endchar;
1124       gchar *in_u8 = g_utf16_to_utf8 (testcases[i].in, -1, NULL, NULL, NULL);
1125       gchar *out_u8 = g_utf16_to_utf8 (testcases[i].out, -1, NULL, NULL, NULL);
1126
1127       g_assert_nonnull (in_u8);
1128       g_assert_nonnull (out_u8);
1129
1130       buf = g_new0 (gunichar2, str_len);
1131       memcpy (buf, testcases[i].in, (str_len) * sizeof (gunichar2));
1132
1133       old_endchar = buf[wcslen (testcases[i].out)];
1134       str_len -= 1;
1135
1136       if (testcases[i].result)
1137         {
1138           /* Given "\\\\?\\C:\\" (len 7, unterminated),
1139            * we should get "C:\\" (len 3, unterminated).
1140            * Put a character different from "\\" (4-th character of the buffer)
1141            * at the end of the unterminated source buffer, into a position
1142            * where NUL-terminator would normally be. Then later test that 4-th character
1143            * in the buffer is still the old "\\".
1144            * After that terminate the string and use normal g_wcscmp0().
1145            */
1146           buf[str_len] = old_endchar - 1;
1147         }
1148
1149       _g_win32_strip_extended_ntobjm_prefix (buf, &str_len);
1150       g_assert_cmpuint (old_endchar, ==, buf[wcslen (testcases[i].out)]);
1151       buf[str_len] = L'\0';
1152       g_assert_cmpwcs (buf, ==, testcases[i].out, in_u8, out_u8);
1153       g_free (buf);
1154       g_free (in_u8);
1155       g_free (out_u8);
1156     }
1157 }
1158
1159 #define g_assert_memcmp(m1, cmp, m2, memlen, m1hex, m2hex, testcase_num) \
1160 G_STMT_START { \
1161   if (memcmp (m1, m2, memlen) cmp 0); else \
1162     g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
1163                                 #m1hex " " #cmp " " #m2hex, m1hex, #cmp, m2hex); \
1164 } G_STMT_END
1165
1166 static gchar *
1167 to_hex (const guchar *buf,
1168         gsize        len)
1169 {
1170   gsize i;
1171   GString *s = g_string_new (NULL);
1172   if (len > 0)
1173     g_string_append_printf (s, "%02x", buf[0]);
1174   for (i = 1; i < len; i++)
1175     g_string_append_printf (s, " %02x", buf[i]);
1176   return g_string_free (s, FALSE);
1177 }
1178
1179 static void
1180 test_win32_zero_terminate_symlink (void)
1181 {
1182   gsize i;
1183 #define TESTCASE(data, len_mod, use_buf, buf_size, terminate, reported_len, returned_string) \
1184  { (const guchar *) data, wcslen (data) * 2 + len_mod, use_buf, buf_size, terminate, reported_len, (guchar *) returned_string},
1185
1186   struct
1187   {
1188     const guchar *data;
1189     gsize         data_size;
1190     gboolean      use_buf;
1191     gsize         buf_size;
1192     gboolean      terminate;
1193     int           reported_len;
1194     const guchar *returned_string;
1195   } testcases[] = {
1196     TESTCASE (L"foobar", +2, TRUE, 12 + 4, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1197     TESTCASE (L"foobar", +2, TRUE, 12 + 3, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1198     TESTCASE (L"foobar", +2, TRUE, 12 + 2, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1199     TESTCASE (L"foobar", +2, TRUE, 12 + 1, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1200     TESTCASE (L"foobar", +2, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1201     TESTCASE (L"foobar", +2, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1202     TESTCASE (L"foobar", +2, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1203     TESTCASE (L"foobar", +2, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a")
1204     TESTCASE (L"foobar", +1, TRUE, 12 + 4, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1205     TESTCASE (L"foobar", +1, TRUE, 12 + 3, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1206     TESTCASE (L"foobar", +1, TRUE, 12 + 2, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1207     TESTCASE (L"foobar", +1, TRUE, 12 + 1, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1208     TESTCASE (L"foobar", +1, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1209     TESTCASE (L"foobar", +1, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1210     TESTCASE (L"foobar", +1, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1211     TESTCASE (L"foobar", +1, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a")
1212     TESTCASE (L"foobar", +0, TRUE, 12 + 4, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1213     TESTCASE (L"foobar", +0, TRUE, 12 + 3, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1214     TESTCASE (L"foobar", +0, TRUE, 12 + 2, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1215     TESTCASE (L"foobar", +0, TRUE, 12 + 1, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1216     TESTCASE (L"foobar", +0, TRUE, 12 + 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1217     TESTCASE (L"foobar", +0, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1218     TESTCASE (L"foobar", +0, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1219     TESTCASE (L"foobar", +0, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a")
1220     TESTCASE (L"foobar", -1, TRUE, 12 + 3, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1221     TESTCASE (L"foobar", -1, TRUE, 12 + 2, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1222     TESTCASE (L"foobar", -1, TRUE, 12 + 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1223     TESTCASE (L"foobar", -1, TRUE, 12 + 0, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1224     TESTCASE (L"foobar", -1, TRUE, 12 - 1, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1225     TESTCASE (L"foobar", -1, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1226     TESTCASE (L"foobar", -1, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a")
1227     TESTCASE (L"foobar", -1, TRUE, 12 - 4, FALSE, 12 - 4, "f\0o\0o\0b\0")
1228     TESTCASE (L"foobar", -2, TRUE, 12 + 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1229     TESTCASE (L"foobar", -2, TRUE, 12 + 1, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1230     TESTCASE (L"foobar", -2, TRUE, 12 + 0, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1231     TESTCASE (L"foobar", -2, TRUE, 12 - 1, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1232     TESTCASE (L"foobar", -2, TRUE, 12 - 2, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1233     TESTCASE (L"foobar", -2, TRUE, 12 - 3, FALSE, 12 - 3, "f\0o\0o\0b\0a")
1234     TESTCASE (L"foobar", -2, TRUE, 12 - 4, FALSE, 12 - 4, "f\0o\0o\0b\0")
1235     TESTCASE (L"foobar", -2, TRUE, 12 - 5, FALSE, 12 - 5, "f\0o\0o\0b")
1236     TESTCASE (L"foobar", +2, TRUE, 12 + 4, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1237     TESTCASE (L"foobar", +2, TRUE, 12 + 3, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1238     TESTCASE (L"foobar", +2, TRUE, 12 + 2, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1239     TESTCASE (L"foobar", +2, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1240     TESTCASE (L"foobar", +2, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0")
1241     TESTCASE (L"foobar", +2, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1242     TESTCASE (L"foobar", +2, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0")
1243     TESTCASE (L"foobar", +2, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0")
1244     TESTCASE (L"foobar", +1, TRUE, 12 + 4, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1245     TESTCASE (L"foobar", +1, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1246     TESTCASE (L"foobar", +1, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1247     TESTCASE (L"foobar", +1, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1248     TESTCASE (L"foobar", +1, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0")
1249     TESTCASE (L"foobar", +1, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1250     TESTCASE (L"foobar", +1, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0")
1251     TESTCASE (L"foobar", +1, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0")
1252     TESTCASE (L"foobar", +0, TRUE, 12 + 4, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1253     TESTCASE (L"foobar", +0, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1254     TESTCASE (L"foobar", +0, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1255     TESTCASE (L"foobar", +0, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1256     TESTCASE (L"foobar", +0, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0")
1257     TESTCASE (L"foobar", +0, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1258     TESTCASE (L"foobar", +0, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0")
1259     TESTCASE (L"foobar", +0, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0")
1260     TESTCASE (L"foobar", -1, TRUE, 12 + 3, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1261     TESTCASE (L"foobar", -1, TRUE, 12 + 2, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1262     TESTCASE (L"foobar", -1, TRUE, 12 + 1, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1263     TESTCASE (L"foobar", -1, TRUE, 12 + 0, TRUE, 12 + 0, "f\0o\0o\0b\0a\0\0\0")
1264     TESTCASE (L"foobar", -1, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1265     TESTCASE (L"foobar", -1, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0")
1266     TESTCASE (L"foobar", -1, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0")
1267     TESTCASE (L"foobar", -1, TRUE, 12 - 4, TRUE, 12 - 4, "f\0o\0o\0\0\0")
1268     TESTCASE (L"foobar", -2, TRUE, 12 + 2, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1269     TESTCASE (L"foobar", -2, TRUE, 12 + 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1270     TESTCASE (L"foobar", -2, TRUE, 12 + 0, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1271     TESTCASE (L"foobar", -2, TRUE, 12 - 1, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1272     TESTCASE (L"foobar", -2, TRUE, 12 - 2, TRUE, 12 - 2, "f\0o\0o\0b\0\0\0")
1273     TESTCASE (L"foobar", -2, TRUE, 12 - 3, TRUE, 12 - 3, "f\0o\0o\0b\0\0")
1274     TESTCASE (L"foobar", -2, TRUE, 12 - 4, TRUE, 12 - 4, "f\0o\0o\0\0\0")
1275     TESTCASE (L"foobar", -2, TRUE, 12 - 5, TRUE, 12 - 5, "f\0o\0o\0\0")
1276     TESTCASE (L"foobar", +2, FALSE, 0, FALSE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1277     TESTCASE (L"foobar", +1, FALSE, 0, FALSE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1278     TESTCASE (L"foobar", +0, FALSE, 0, FALSE, 12 + 0, "f\0o\0o\0b\0a\0r\0")
1279     TESTCASE (L"foobar", -1, FALSE, 0, FALSE, 12 - 1, "f\0o\0o\0b\0a\0r")
1280     TESTCASE (L"foobar", -2, FALSE, 0, FALSE, 12 - 2, "f\0o\0o\0b\0a\0")
1281     TESTCASE (L"foobar", +2, FALSE, 0, TRUE, 12 + 2, "f\0o\0o\0b\0a\0r\0\0\0")
1282     TESTCASE (L"foobar", +1, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1283     TESTCASE (L"foobar", +0, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1284     TESTCASE (L"foobar", -1, FALSE, 0, TRUE, 12 + 1, "f\0o\0o\0b\0a\0r\0\0")
1285     TESTCASE (L"foobar", -2, FALSE, 0, TRUE, 12 - 1, "f\0o\0o\0b\0a\0\0")
1286     TESTCASE (L"x", +2, TRUE, 2 + 4, FALSE, 2 + 2, "x\0\0\0")
1287     TESTCASE (L"x", +2, TRUE, 2 + 3, FALSE, 2 + 2, "x\0\0\0")
1288     TESTCASE (L"x", +2, TRUE, 2 + 2, FALSE, 2 + 2, "x\0\0\0")
1289     TESTCASE (L"x", +2, TRUE, 2 + 1, FALSE, 2 + 1, "x\0\0")
1290     TESTCASE (L"x", +2, TRUE, 2 + 0, FALSE, 2 + 0, "x\0")
1291     TESTCASE (L"x", +2, TRUE, 2 - 1, FALSE, 2 - 1, "x")
1292     TESTCASE (L"x", +2, TRUE, 2 - 2, FALSE, 2 - 2, "")
1293     TESTCASE (L"x", +1, TRUE, 2 + 3, FALSE, 2 + 1, "x\0\0")
1294     TESTCASE (L"x", +1, TRUE, 2 + 2, FALSE, 2 + 1, "x\0\0")
1295     TESTCASE (L"x", +1, TRUE, 2 + 1, FALSE, 2 + 1, "x\0\0")
1296     TESTCASE (L"x", +1, TRUE, 2 + 0, FALSE, 2 + 0, "x\0")
1297     TESTCASE (L"x", +1, TRUE, 2 - 1, FALSE, 2 - 1, "x")
1298     TESTCASE (L"x", +1, TRUE, 2 - 2, FALSE, 2 - 2, "")
1299     TESTCASE (L"x", +0, TRUE, 2 + 2, FALSE, 2 + 0, "x\0")
1300     TESTCASE (L"x", +0, TRUE, 2 + 1, FALSE, 2 + 0, "x\0")
1301     TESTCASE (L"x", +0, TRUE, 2 + 0, FALSE, 2 + 0, "x\0")
1302     TESTCASE (L"x", +0, TRUE, 2 - 1, FALSE, 2 - 1, "x")
1303     TESTCASE (L"x", +0, TRUE, 2 - 2, FALSE, 2 - 2, "")
1304     TESTCASE (L"x", -1, TRUE, 2 + 1, FALSE, 2 - 1, "x")
1305     TESTCASE (L"x", -1, TRUE, 2 + 0, FALSE, 2 - 1, "x")
1306     TESTCASE (L"x", -1, TRUE, 2 - 1, FALSE, 2 - 1, "x")
1307     TESTCASE (L"x", -1, TRUE, 2 - 2, FALSE, 2 - 2, "")
1308     TESTCASE (L"x", -2, TRUE, 2 + 0, FALSE, 2 - 2, "")
1309     TESTCASE (L"x", -2, TRUE, 2 - 1, FALSE, 2 - 2, "")
1310     TESTCASE (L"x", -2, TRUE, 2 - 2, FALSE, 2 - 2, "")
1311     TESTCASE (L"x", +2, TRUE, 2 + 4, TRUE, 2 + 2, "x\0\0\0")
1312     TESTCASE (L"x", +2, TRUE, 2 + 3, TRUE, 2 + 2, "x\0\0\0")
1313     TESTCASE (L"x", +2, TRUE, 2 + 2, TRUE, 2 + 2, "x\0\0\0")
1314     TESTCASE (L"x", +2, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0")
1315     TESTCASE (L"x", +2, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0")
1316     TESTCASE (L"x", +2, TRUE, 2 - 1, TRUE, 2 - 1, "\0")
1317     TESTCASE (L"x", +2, TRUE, 2 - 2, TRUE, 2 - 2, "")
1318     TESTCASE (L"x", +1, TRUE, 2 + 3, TRUE, 2 + 1, "x\0\0")
1319     TESTCASE (L"x", +1, TRUE, 2 + 2, TRUE, 2 + 1, "x\0\0")
1320     TESTCASE (L"x", +1, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0")
1321     TESTCASE (L"x", +1, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0")
1322     TESTCASE (L"x", +1, TRUE, 2 - 1, TRUE, 2 - 1, "\0")
1323     TESTCASE (L"x", +1, TRUE, 2 - 2, TRUE, 2 - 2, "")
1324     TESTCASE (L"x", +0, TRUE, 2 + 2, TRUE, 2 + 1, "x\0\0")
1325     TESTCASE (L"x", +0, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0")
1326     TESTCASE (L"x", +0, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0")
1327     TESTCASE (L"x", +0, TRUE, 2 - 1, TRUE, 2 - 1, "\0")
1328     TESTCASE (L"x", +0, TRUE, 2 - 2, TRUE, 2 - 2, "")
1329     TESTCASE (L"x", -1, TRUE, 2 + 1, TRUE, 2 + 1, "x\0\0")
1330     TESTCASE (L"x", -1, TRUE, 2 + 0, TRUE, 2 + 0, "\0\0")
1331     TESTCASE (L"x", -1, TRUE, 2 - 1, TRUE, 2 - 1, "\0")
1332     TESTCASE (L"x", -1, TRUE, 2 - 2, TRUE, 2 - 2, "")
1333     TESTCASE (L"x", -2, TRUE, 2 + 0, TRUE, 2 - 2, "")
1334     TESTCASE (L"x", -2, TRUE, 2 - 1, TRUE, 2 - 2, "")
1335     TESTCASE (L"x", -2, TRUE, 2 - 2, TRUE, 2 - 2, "")
1336     TESTCASE (L"x", +2, FALSE, 0, FALSE, 2 + 2, "x\0\0\0")
1337     TESTCASE (L"x", +1, FALSE, 0, FALSE, 2 + 1, "x\0\0")
1338     TESTCASE (L"x", +0, FALSE, 0, FALSE, 2 + 0, "x\0")
1339     TESTCASE (L"x", -1, FALSE, 0, FALSE, 2 - 1, "x")
1340     TESTCASE (L"x", -2, FALSE, 0, FALSE, 2 - 2, "")
1341     TESTCASE (L"x", +2, FALSE, 0, TRUE, 2 + 2, "x\0\0\0")
1342     TESTCASE (L"x", +1, FALSE, 0, TRUE, 2 + 1, "x\0\0")
1343     TESTCASE (L"x", +0, FALSE, 0, TRUE, 2 + 1, "x\0\0")
1344     TESTCASE (L"x", -1, FALSE, 0, TRUE, 2 + 1, "x\0\0")
1345     TESTCASE (L"x", -2, FALSE, 0, TRUE, 2 - 2, "")
1346     { 0, },
1347   };
1348 #undef TESTCASE
1349
1350   for (i = 0; testcases[i].data != NULL; i++)
1351     {
1352       gunichar2 *buf;
1353       int result;
1354       gchar *buf_hex, *expected_hex;
1355       if (testcases[i].use_buf)
1356         buf = g_malloc0 (testcases[i].buf_size + 1); /* +1 to ensure it succeeds with buf_size == 0 */
1357       else
1358         buf = NULL;
1359       result = _g_win32_copy_and_maybe_terminate (testcases[i].data,
1360                                                   testcases[i].data_size,
1361                                                   testcases[i].use_buf ? buf : NULL,
1362                                                   testcases[i].buf_size,
1363                                                   testcases[i].use_buf ? NULL : &buf,
1364                                                   testcases[i].terminate);
1365       if (testcases[i].reported_len != result)
1366         g_error ("Test %" G_GSIZE_FORMAT " failed, result %d != %d", i, result, testcases[i].reported_len);
1367       if (buf == NULL && testcases[i].buf_size != 0)
1368         g_error ("Test %" G_GSIZE_FORMAT " failed, buf == NULL", i);
1369       g_assert_cmpint (testcases[i].reported_len, ==, result);
1370       if ((testcases[i].use_buf && testcases[i].buf_size != 0) ||
1371           (!testcases[i].use_buf && testcases[i].reported_len != 0))
1372         {
1373           g_assert_nonnull (buf);
1374           buf_hex = to_hex ((const guchar *) buf, result);
1375           expected_hex = to_hex (testcases[i].returned_string, testcases[i].reported_len);
1376           if (memcmp (buf, testcases[i].returned_string, result) != 0)
1377             g_error ("Test %" G_GSIZE_FORMAT " failed:\n%s !=\n%s", i, buf_hex, expected_hex);
1378           g_assert_memcmp (buf, ==, testcases[i].returned_string, testcases[i].reported_len, buf_hex, expected_hex, testcases[i].line);
1379           g_free (buf_hex);
1380           g_free (expected_hex);
1381         }
1382       g_free (buf);
1383     }
1384 }
1385
1386 #endif
1387
1388 int
1389 main (int   argc,
1390       char *argv[])
1391 {
1392   g_setenv ("LC_ALL", "C", TRUE);
1393   g_test_init (&argc, &argv, NULL);
1394
1395   g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/merge_requests/");
1396
1397 #ifdef G_OS_WIN32
1398   g_test_add_func ("/fileutils/stdio-win32-pathstrip", test_win32_pathstrip);
1399   g_test_add_func ("/fileutils/stdio-win32-zero-terminate-symlink", test_win32_zero_terminate_symlink);
1400 #endif
1401   g_test_add_func ("/fileutils/build-path", test_build_path);
1402   g_test_add_func ("/fileutils/build-pathv", test_build_pathv);
1403   g_test_add_func ("/fileutils/build-filename", test_build_filename);
1404   g_test_add_func ("/fileutils/build-filenamev", test_build_filenamev);
1405   g_test_add_func ("/fileutils/mkdir-with-parents", test_mkdir_with_parents);
1406   g_test_add_func ("/fileutils/format-size-for-display", test_format_size_for_display);
1407   g_test_add_func ("/fileutils/errors", test_file_errors);
1408   g_test_add_func ("/fileutils/basename", test_basename);
1409   g_test_add_func ("/fileutils/dir-make-tmp", test_dir_make_tmp);
1410   g_test_add_func ("/fileutils/file-open-tmp", test_file_open_tmp);
1411   g_test_add_func ("/fileutils/mkstemp", test_mkstemp);
1412   g_test_add_func ("/fileutils/mkdtemp", test_mkdtemp);
1413   g_test_add_func ("/fileutils/set-contents", test_set_contents);
1414   g_test_add_func ("/fileutils/read-link", test_read_link);
1415   g_test_add_func ("/fileutils/stdio-wrappers", test_stdio_wrappers);
1416   g_test_add_func ("/fileutils/fopen-modes", test_fopen_modes);
1417
1418   return g_test_run ();
1419 }