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