Branch data Line data Source code
1 : : /* gfileutils.c - File utility functions
2 : : *
3 : : * Copyright 2000 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General Public License
18 : : * along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include "config.h"
22 : : #include "glibconfig.h"
23 : :
24 : : #include <sys/stat.h>
25 : : #include <stdio.h>
26 : : #include <stdlib.h>
27 : : #include <stdarg.h>
28 : : #include <stdint.h>
29 : : #include <string.h>
30 : : #include <errno.h>
31 : : #include <sys/types.h>
32 : : #include <sys/stat.h>
33 : : #include <fcntl.h>
34 : : #include <stdlib.h>
35 : :
36 : : #ifdef G_OS_UNIX
37 : : #include <unistd.h>
38 : : #endif
39 : : #ifdef G_OS_WIN32
40 : : #include <windows.h>
41 : : #include <io.h>
42 : : #endif /* G_OS_WIN32 */
43 : :
44 : : #ifndef S_ISLNK
45 : : #define S_ISLNK(x) 0
46 : : #endif
47 : :
48 : : #ifndef O_BINARY
49 : : #define O_BINARY 0
50 : : #endif
51 : :
52 : : #ifndef O_CLOEXEC
53 : : #define O_CLOEXEC 0
54 : : #endif
55 : :
56 : : #include "gfileutils.h"
57 : :
58 : : #include "gstdio.h"
59 : : #include "gstdioprivate.h"
60 : : #include "glibintl.h"
61 : :
62 : :
63 : : /**
64 : : * GFileError:
65 : : * @G_FILE_ERROR_EXIST: Operation not permitted; only the owner of
66 : : * the file (or other resource) or processes with special privileges
67 : : * can perform the operation.
68 : : * @G_FILE_ERROR_ISDIR: File is a directory; you cannot open a directory
69 : : * for writing, or create or remove hard links to it.
70 : : * @G_FILE_ERROR_ACCES: Permission denied; the file permissions do not
71 : : * allow the attempted operation.
72 : : * @G_FILE_ERROR_NAMETOOLONG: Filename too long.
73 : : * @G_FILE_ERROR_NOENT: No such file or directory. This is a "file
74 : : * doesn't exist" error for ordinary files that are referenced in
75 : : * contexts where they are expected to already exist.
76 : : * @G_FILE_ERROR_NOTDIR: A file that isn't a directory was specified when
77 : : * a directory is required.
78 : : * @G_FILE_ERROR_NXIO: No such device or address. The system tried to
79 : : * use the device represented by a file you specified, and it
80 : : * couldn't find the device. This can mean that the device file was
81 : : * installed incorrectly, or that the physical device is missing or
82 : : * not correctly attached to the computer.
83 : : * @G_FILE_ERROR_NODEV: The underlying file system of the specified file
84 : : * does not support memory mapping.
85 : : * @G_FILE_ERROR_ROFS: The directory containing the new link can't be
86 : : * modified because it's on a read-only file system.
87 : : * @G_FILE_ERROR_TXTBSY: Text file busy.
88 : : * @G_FILE_ERROR_FAULT: You passed in a pointer to bad memory.
89 : : * (GLib won't reliably return this, don't pass in pointers to bad
90 : : * memory.)
91 : : * @G_FILE_ERROR_LOOP: Too many levels of symbolic links were encountered
92 : : * in looking up a file name. This often indicates a cycle of symbolic
93 : : * links.
94 : : * @G_FILE_ERROR_NOSPC: No space left on device; write operation on a
95 : : * file failed because the disk is full.
96 : : * @G_FILE_ERROR_NOMEM: No memory available. The system cannot allocate
97 : : * more virtual memory because its capacity is full.
98 : : * @G_FILE_ERROR_MFILE: The current process has too many files open and
99 : : * can't open any more. Duplicate descriptors do count toward this
100 : : * limit.
101 : : * @G_FILE_ERROR_NFILE: There are too many distinct file openings in the
102 : : * entire system.
103 : : * @G_FILE_ERROR_BADF: Bad file descriptor; for example, I/O on a
104 : : * descriptor that has been closed or reading from a descriptor open
105 : : * only for writing (or vice versa).
106 : : * @G_FILE_ERROR_INVAL: Invalid argument. This is used to indicate
107 : : * various kinds of problems with passing the wrong argument to a
108 : : * library function.
109 : : * @G_FILE_ERROR_PIPE: Broken pipe; there is no process reading from the
110 : : * other end of a pipe. Every library function that returns this
111 : : * error code also generates a 'SIGPIPE' signal; this signal
112 : : * terminates the program if not handled or blocked. Thus, your
113 : : * program will never actually see this code unless it has handled
114 : : * or blocked 'SIGPIPE'.
115 : : * @G_FILE_ERROR_AGAIN: Resource temporarily unavailable; the call might
116 : : * work if you try again later.
117 : : * @G_FILE_ERROR_INTR: Interrupted function call; an asynchronous signal
118 : : * occurred and prevented completion of the call. When this
119 : : * happens, you should try the call again.
120 : : * @G_FILE_ERROR_IO: Input/output error; usually used for physical read
121 : : * or write errors. i.e. the disk or other physical device hardware
122 : : * is returning errors.
123 : : * @G_FILE_ERROR_PERM: Operation not permitted; only the owner of the
124 : : * file (or other resource) or processes with special privileges can
125 : : * perform the operation.
126 : : * @G_FILE_ERROR_NOSYS: Function not implemented; this indicates that
127 : : * the system is missing some functionality.
128 : : * @G_FILE_ERROR_FAILED: Does not correspond to a UNIX error code; this
129 : : * is the standard "failed for unspecified reason" error code present
130 : : * in all #GError error code enumerations. Returned if no specific
131 : : * code applies.
132 : : *
133 : : * Values corresponding to @errno codes returned from file operations
134 : : * on UNIX. Unlike @errno codes, GFileError values are available on
135 : : * all systems, even Windows. The exact meaning of each code depends
136 : : * on what sort of file operation you were performing; the UNIX
137 : : * documentation gives more details. The following error code descriptions
138 : : * come from the GNU C Library manual, and are under the copyright
139 : : * of that manual.
140 : : *
141 : : * It's not very portable to make detailed assumptions about exactly
142 : : * which errors will be returned from a given operation. Some errors
143 : : * don't occur on some systems, etc., sometimes there are subtle
144 : : * differences in when a system will report a given error, etc.
145 : : */
146 : :
147 : : /**
148 : : * G_FILE_ERROR:
149 : : *
150 : : * Error domain for file operations. Errors in this domain will
151 : : * be from the #GFileError enumeration. See #GError for information
152 : : * on error domains.
153 : : */
154 : :
155 : : /**
156 : : * GFileTest:
157 : : * @G_FILE_TEST_IS_REGULAR: %TRUE if the file is a regular file
158 : : * (not a directory). Note that this test will also return %TRUE
159 : : * if the tested file is a symlink to a regular file.
160 : : * @G_FILE_TEST_IS_SYMLINK: %TRUE if the file is a symlink.
161 : : * @G_FILE_TEST_IS_DIR: %TRUE if the file is a directory.
162 : : * @G_FILE_TEST_IS_EXECUTABLE: %TRUE if the file is executable.
163 : : * @G_FILE_TEST_EXISTS: %TRUE if the file exists. It may or may not
164 : : * be a regular file.
165 : : *
166 : : * A test to perform on a file using g_file_test().
167 : : */
168 : :
169 : : /**
170 : : * g_mkdir_with_parents:
171 : : * @pathname: (type filename): a pathname in the GLib file name encoding
172 : : * @mode: permissions to use for newly created directories
173 : : *
174 : : * Create a directory if it doesn't already exist. Create intermediate
175 : : * parent directories as needed, too.
176 : : *
177 : : * Returns: 0 if the directory already exists, or was successfully
178 : : * created. Returns -1 if an error occurred, with errno set.
179 : : *
180 : : * Since: 2.8
181 : : */
182 : : int
183 : 1995 : g_mkdir_with_parents (const gchar *pathname,
184 : : int mode)
185 : : {
186 : : gchar *fn, *p;
187 : :
188 : 1995 : if (pathname == NULL || *pathname == '\0')
189 : : {
190 : 2 : errno = EINVAL;
191 : 2 : return -1;
192 : : }
193 : :
194 : : /* try to create the full path first */
195 : 1993 : if (g_mkdir (pathname, mode) == 0)
196 : 65 : return 0;
197 : 1928 : else if (errno == EEXIST)
198 : : {
199 : 198 : if (!g_file_test (pathname, G_FILE_TEST_IS_DIR))
200 : : {
201 : 4 : errno = ENOTDIR;
202 : 4 : return -1;
203 : : }
204 : 194 : return 0;
205 : : }
206 : :
207 : : /* walk the full path and try creating each element */
208 : 1730 : fn = g_strdup (pathname);
209 : :
210 : 1730 : if (g_path_is_absolute (fn))
211 : 1730 : p = (gchar *) g_path_skip_root (fn);
212 : : else
213 : 0 : p = fn;
214 : :
215 : 625 : do
216 : : {
217 : 125012 : while (*p && !G_IS_DIR_SEPARATOR (*p))
218 : 113168 : p++;
219 : :
220 : 11844 : if (!*p)
221 : 1724 : p = NULL;
222 : : else
223 : 10120 : *p = '\0';
224 : :
225 : 11844 : if (!g_file_test (fn, G_FILE_TEST_EXISTS))
226 : : {
227 : 5432 : if (g_mkdir (fn, mode) == -1 && errno != EEXIST)
228 : : {
229 : 3 : int errno_save = errno;
230 : 3 : if (errno != ENOENT || !p)
231 : : {
232 : 3 : g_free (fn);
233 : 3 : errno = errno_save;
234 : 3 : return -1;
235 : : }
236 : 0 : }
237 : 1950 : }
238 : 6412 : else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
239 : : {
240 : 4 : g_free (fn);
241 : 4 : errno = ENOTDIR;
242 : 4 : return -1;
243 : : }
244 : 11837 : if (p)
245 : : {
246 : 10114 : *p++ = G_DIR_SEPARATOR;
247 : 14111 : while (*p && G_IS_DIR_SEPARATOR (*p))
248 : 8 : p++;
249 : 3989 : }
250 : 4612 : }
251 : 11837 : while (p);
252 : :
253 : 1723 : g_free (fn);
254 : :
255 : 1723 : return 0;
256 : 667 : }
257 : :
258 : : /**
259 : : * g_file_test:
260 : : * @filename: (type filename): a filename to test in the
261 : : * GLib file name encoding
262 : : * @test: bitfield of #GFileTest flags
263 : : *
264 : : * Returns %TRUE if any of the tests in the bitfield @test are
265 : : * %TRUE. For example, `(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)`
266 : : * will return %TRUE if the file exists; the check whether it's a
267 : : * directory doesn't matter since the existence test is %TRUE. With
268 : : * the current set of available tests, there's no point passing in
269 : : * more than one test at a time.
270 : : *
271 : : * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
272 : : * so for a symbolic link to a regular file g_file_test() will return
273 : : * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
274 : : *
275 : : * Note, that for a dangling symbolic link g_file_test() will return
276 : : * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
277 : : *
278 : : * You should never use g_file_test() to test whether it is safe
279 : : * to perform an operation, because there is always the possibility
280 : : * of the condition changing before you actually perform the operation,
281 : : * see [TOCTOU](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use).
282 : : *
283 : : * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
284 : : * to know whether it is safe to write to a file without being
285 : : * tricked into writing into a different location. It doesn't work!
286 : : *
287 : : * |[<!-- language="C" -->
288 : : * // DON'T DO THIS
289 : : * if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK))
290 : : * {
291 : : * fd = g_open (filename, O_WRONLY);
292 : : * // write to fd
293 : : * }
294 : : *
295 : : * // DO THIS INSTEAD
296 : : * fd = g_open (filename, O_WRONLY | O_NOFOLLOW | O_CLOEXEC);
297 : : * if (fd == -1)
298 : : * {
299 : : * // check error
300 : : * if (errno == ELOOP)
301 : : * // file is a symlink and can be ignored
302 : : * else
303 : : * // handle errors as before
304 : : * }
305 : : * else
306 : : * {
307 : : * // write to fd
308 : : * }
309 : : * ]|
310 : : *
311 : : * Another thing to note is that %G_FILE_TEST_EXISTS and
312 : : * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
313 : : * system call. This usually doesn't matter, but if your program
314 : : * is setuid or setgid it means that these tests will give you
315 : : * the answer for the real user ID and group ID, rather than the
316 : : * effective user ID and group ID.
317 : : *
318 : : * On Windows, there are no symlinks, so testing for
319 : : * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for
320 : : * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and
321 : : * its name indicates that it is executable, checking for well-known
322 : : * extensions and those listed in the `PATHEXT` environment variable.
323 : : *
324 : : * Returns: whether a test was %TRUE
325 : : **/
326 : : gboolean
327 : 236698 : g_file_test (const gchar *filename,
328 : : GFileTest test)
329 : : {
330 : : #ifdef G_OS_WIN32
331 : : DWORD attributes;
332 : : wchar_t *wfilename;
333 : : #endif
334 : :
335 : 236698 : g_return_val_if_fail (filename != NULL, FALSE);
336 : :
337 : : #ifdef G_OS_WIN32
338 : : /* stuff missing in std vc6 api */
339 : : # ifndef INVALID_FILE_ATTRIBUTES
340 : : # define INVALID_FILE_ATTRIBUTES -1
341 : : # endif
342 : : # ifndef FILE_ATTRIBUTE_DEVICE
343 : : # define FILE_ATTRIBUTE_DEVICE 64
344 : : # endif
345 : 219036 : wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
346 : :
347 : 219036 : if (wfilename == NULL)
348 : 0 : return FALSE;
349 : :
350 : 219036 : attributes = GetFileAttributesW (wfilename);
351 : :
352 : 219036 : g_free (wfilename);
353 : :
354 : 219036 : if (attributes == INVALID_FILE_ATTRIBUTES)
355 : 212913 : return FALSE;
356 : :
357 : 6123 : if (test & G_FILE_TEST_EXISTS)
358 : 2742 : return TRUE;
359 : :
360 : 3381 : if (test & G_FILE_TEST_IS_REGULAR)
361 : : {
362 : 555 : if ((attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0)
363 : 542 : return TRUE;
364 : 13 : }
365 : :
366 : 2839 : if (test & G_FILE_TEST_IS_DIR)
367 : : {
368 : 2767 : if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
369 : 2713 : return TRUE;
370 : 54 : }
371 : :
372 : : /* "while" so that we can exit this "loop" with a simple "break" */
373 : 126 : while (test & G_FILE_TEST_IS_EXECUTABLE)
374 : : {
375 : 56 : const gchar *lastdot = strrchr (filename, '.');
376 : 56 : const gchar *pathext = NULL, *p;
377 : : size_t extlen;
378 : :
379 : 56 : if (lastdot == NULL)
380 : 0 : break;
381 : :
382 : 56 : if (_stricmp (lastdot, ".exe") == 0 ||
383 : 48 : _stricmp (lastdot, ".cmd") == 0 ||
384 : 0 : _stricmp (lastdot, ".bat") == 0 ||
385 : 0 : _stricmp (lastdot, ".com") == 0)
386 : 56 : return TRUE;
387 : :
388 : : /* Check if it is one of the types listed in %PATHEXT% */
389 : :
390 : 0 : pathext = g_getenv ("PATHEXT");
391 : 0 : if (pathext == NULL)
392 : 0 : break;
393 : :
394 : 0 : pathext = g_utf8_casefold (pathext, -1);
395 : :
396 : 0 : lastdot = g_utf8_casefold (lastdot, -1);
397 : 0 : extlen = strlen (lastdot);
398 : :
399 : 0 : p = pathext;
400 : 0 : while (TRUE)
401 : : {
402 : 0 : const gchar *q = strchr (p, ';');
403 : 0 : if (q == NULL)
404 : 0 : q = p + strlen (p);
405 : 0 : if (extlen == (size_t) (q - p) &&
406 : 0 : memcmp (lastdot, p, extlen) == 0)
407 : : {
408 : 0 : g_free ((gchar *) pathext);
409 : 0 : g_free ((gchar *) lastdot);
410 : 0 : return TRUE;
411 : : }
412 : 0 : if (*q)
413 : 0 : p = q + 1;
414 : : else
415 : 0 : break;
416 : : }
417 : :
418 : 0 : g_free ((gchar *) pathext);
419 : 0 : g_free ((gchar *) lastdot);
420 : 0 : break;
421 : : }
422 : :
423 : 70 : return FALSE;
424 : : #else
425 : 17660 : if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
426 : 3813 : return TRUE;
427 : :
428 : 13847 : if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
429 : : {
430 : 667 : if (getuid () != 0)
431 : 667 : return TRUE;
432 : :
433 : : /* For root, on some POSIX systems, access (filename, X_OK)
434 : : * will succeed even if no executable bits are set on the
435 : : * file. We fall through to a stat test to avoid that.
436 : : */
437 : : }
438 : : else
439 : 13180 : test &= ~G_FILE_TEST_IS_EXECUTABLE;
440 : :
441 : 13180 : if (test & G_FILE_TEST_IS_SYMLINK)
442 : : {
443 : : struct stat s;
444 : :
445 : 132 : if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
446 : 1 : return TRUE;
447 : : }
448 : :
449 : 13179 : if (test & (G_FILE_TEST_IS_REGULAR |
450 : : G_FILE_TEST_IS_DIR |
451 : : G_FILE_TEST_IS_EXECUTABLE))
452 : : {
453 : : struct stat s;
454 : :
455 : 7395 : if (stat (filename, &s) == 0)
456 : : {
457 : 4881 : if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
458 : 4107 : return TRUE;
459 : :
460 : 4761 : if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
461 : 3987 : return TRUE;
462 : :
463 : : /* The extra test for root when access (file, X_OK) succeeds.
464 : : */
465 : 774 : if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
466 : 0 : ((s.st_mode & S_IXOTH) ||
467 : 0 : (s.st_mode & S_IXUSR) ||
468 : 0 : (s.st_mode & S_IXGRP)))
469 : 0 : return TRUE;
470 : : }
471 : : }
472 : :
473 : 9072 : return FALSE;
474 : : #endif
475 : 219037 : }
476 : :
477 : 1591 : G_DEFINE_QUARK (g-file-error-quark, g_file_error)
478 : :
479 : : /**
480 : : * g_file_error_from_errno:
481 : : * @err_no: an "errno" value
482 : : *
483 : : * Gets a #GFileError constant based on the passed-in @err_no.
484 : : *
485 : : * For example, if you pass in `EEXIST` this function returns
486 : : * %G_FILE_ERROR_EXIST. Unlike `errno` values, you can portably
487 : : * assume that all #GFileError values will exist.
488 : : *
489 : : * Normally a #GFileError value goes into a #GError returned
490 : : * from a function that manipulates files. So you would use
491 : : * g_file_error_from_errno() when constructing a #GError.
492 : : *
493 : : * Returns: #GFileError corresponding to the given @err_no
494 : : **/
495 : : GFileError
496 : 5200 : g_file_error_from_errno (gint err_no)
497 : : {
498 : 5200 : switch (err_no)
499 : : {
500 : : #ifdef EEXIST
501 : 16 : case EEXIST:
502 : 19 : return G_FILE_ERROR_EXIST;
503 : : #endif
504 : :
505 : : #ifdef EISDIR
506 : 61 : case EISDIR:
507 : 63 : return G_FILE_ERROR_ISDIR;
508 : : #endif
509 : :
510 : : #ifdef EACCES
511 : 33 : case EACCES:
512 : 56 : return G_FILE_ERROR_ACCES;
513 : : #endif
514 : :
515 : : #ifdef ENAMETOOLONG
516 : 3 : case ENAMETOOLONG:
517 : 5 : return G_FILE_ERROR_NAMETOOLONG;
518 : : #endif
519 : :
520 : : #ifdef ENOENT
521 : 1545 : case ENOENT:
522 : 1597 : return G_FILE_ERROR_NOENT;
523 : : #endif
524 : :
525 : : #ifdef ENOTDIR
526 : 138 : case ENOTDIR:
527 : 140 : return G_FILE_ERROR_NOTDIR;
528 : : #endif
529 : :
530 : : #ifdef ENXIO
531 : 10 : case ENXIO:
532 : 12 : return G_FILE_ERROR_NXIO;
533 : : #endif
534 : :
535 : : #ifdef ENODEV
536 : 2 : case ENODEV:
537 : 4 : return G_FILE_ERROR_NODEV;
538 : : #endif
539 : :
540 : : #ifdef EROFS
541 : 2 : case EROFS:
542 : 4 : return G_FILE_ERROR_ROFS;
543 : : #endif
544 : :
545 : : #ifdef ETXTBSY
546 : 2 : case ETXTBSY:
547 : 4 : return G_FILE_ERROR_TXTBSY;
548 : : #endif
549 : :
550 : : #ifdef EFAULT
551 : 2 : case EFAULT:
552 : 4 : return G_FILE_ERROR_FAULT;
553 : : #endif
554 : :
555 : : #ifdef ELOOP
556 : 2 : case ELOOP:
557 : 4 : return G_FILE_ERROR_LOOP;
558 : : #endif
559 : :
560 : : #ifdef ENOSPC
561 : 2 : case ENOSPC:
562 : 4 : return G_FILE_ERROR_NOSPC;
563 : : #endif
564 : :
565 : : #ifdef ENOMEM
566 : 2 : case ENOMEM:
567 : 4 : return G_FILE_ERROR_NOMEM;
568 : : #endif
569 : :
570 : : #ifdef EMFILE
571 : 2 : case EMFILE:
572 : 4 : return G_FILE_ERROR_MFILE;
573 : : #endif
574 : :
575 : : #ifdef ENFILE
576 : 2 : case ENFILE:
577 : 4 : return G_FILE_ERROR_NFILE;
578 : : #endif
579 : :
580 : : #ifdef EBADF
581 : 38 : case EBADF:
582 : 40 : return G_FILE_ERROR_BADF;
583 : : #endif
584 : :
585 : : #ifdef EINVAL
586 : 5 : case EINVAL:
587 : 8 : return G_FILE_ERROR_INVAL;
588 : : #endif
589 : :
590 : : #ifdef EPIPE
591 : 8 : case EPIPE:
592 : 10 : return G_FILE_ERROR_PIPE;
593 : : #endif
594 : :
595 : : #ifdef EAGAIN
596 : 119 : case EAGAIN:
597 : 121 : return G_FILE_ERROR_AGAIN;
598 : : #endif
599 : :
600 : : #ifdef EINTR
601 : 2 : case EINTR:
602 : 4 : return G_FILE_ERROR_INTR;
603 : : #endif
604 : :
605 : : #ifdef EIO
606 : 2 : case EIO:
607 : 4 : return G_FILE_ERROR_IO;
608 : : #endif
609 : :
610 : : #ifdef EPERM
611 : 2 : case EPERM:
612 : 4 : return G_FILE_ERROR_PERM;
613 : : #endif
614 : :
615 : : #ifdef ENOSYS
616 : 2 : case ENOSYS:
617 : 4 : return G_FILE_ERROR_NOSYS;
618 : : #endif
619 : :
620 : 3021 : default:
621 : 3077 : return G_FILE_ERROR_FAILED;
622 : : }
623 : 177 : }
624 : :
625 : : static char *
626 : : format_error_message (const gchar *filename,
627 : : const gchar *format_string,
628 : : int saved_errno) G_GNUC_FORMAT(2);
629 : :
630 : : #pragma GCC diagnostic push
631 : : #pragma GCC diagnostic ignored "-Wformat-nonliteral"
632 : :
633 : : static char *
634 : 69 : format_error_message (const gchar *filename,
635 : : const gchar *format_string,
636 : : int saved_errno)
637 : : {
638 : : gchar *display_name;
639 : : gchar *msg;
640 : :
641 : 69 : display_name = g_filename_display_name (filename);
642 : 69 : msg = g_strdup_printf (format_string, display_name, g_strerror (saved_errno));
643 : 69 : g_free (display_name);
644 : :
645 : 69 : return msg;
646 : : }
647 : :
648 : : #pragma GCC diagnostic pop
649 : :
650 : : /* format string must have two '%s':
651 : : *
652 : : * - the place for the filename
653 : : * - the place for the strerror
654 : : */
655 : : static void
656 : 69 : set_file_error (GError **error,
657 : : const gchar *filename,
658 : : const gchar *format_string,
659 : : int saved_errno)
660 : : {
661 : 69 : char *msg = format_error_message (filename, format_string, saved_errno);
662 : :
663 : 97 : g_set_error_literal (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
664 : 28 : msg);
665 : 69 : g_free (msg);
666 : 69 : }
667 : :
668 : : static gboolean
669 : 462 : get_contents_stdio (const gchar *filename,
670 : : FILE *f,
671 : : gchar **contents,
672 : : gsize *length,
673 : : GError **error)
674 : : {
675 : : gchar buf[4096];
676 : : gsize bytes; /* always <= sizeof(buf) */
677 : 462 : gchar *str = NULL;
678 : 462 : gsize total_bytes = 0;
679 : 462 : gsize total_allocated = 0;
680 : : gchar *tmp;
681 : : gchar *display_filename;
682 : :
683 : 462 : g_assert (f != NULL);
684 : :
685 : 23958 : while (!feof (f))
686 : : {
687 : : gint save_errno;
688 : :
689 : 23516 : bytes = fread (buf, 1, sizeof (buf), f);
690 : 23516 : save_errno = errno;
691 : :
692 : 23516 : if (total_bytes > G_MAXSIZE - bytes)
693 : 0 : goto file_too_large;
694 : :
695 : : /* Possibility of overflow eliminated above. */
696 : 24293 : while (total_bytes + bytes >= total_allocated)
697 : : {
698 : 777 : if (str)
699 : : {
700 : 315 : if (total_allocated > G_MAXSIZE / 2)
701 : 0 : goto file_too_large;
702 : 315 : total_allocated *= 2;
703 : 315 : }
704 : : else
705 : : {
706 : 462 : total_allocated = MIN (bytes + 1, sizeof (buf));
707 : : }
708 : :
709 : 777 : tmp = g_try_realloc (str, total_allocated);
710 : :
711 : 777 : if (tmp == NULL)
712 : : {
713 : 0 : char *display_size = g_format_size_full (total_allocated, G_FORMAT_SIZE_LONG_FORMAT);
714 : 0 : display_filename = g_filename_display_name (filename);
715 : 0 : g_set_error (error,
716 : 0 : G_FILE_ERROR,
717 : : G_FILE_ERROR_NOMEM,
718 : : /* Translators: the first %s contains the file size
719 : : * (already formatted with units), and the second %s
720 : : * contains the file name */
721 : 0 : _("Could not allocate %s to read file “%s”"),
722 : 0 : display_size,
723 : 0 : display_filename);
724 : 0 : g_free (display_filename);
725 : 0 : g_free (display_size);
726 : :
727 : 0 : goto error;
728 : : }
729 : :
730 : 777 : str = tmp;
731 : : }
732 : :
733 : 23516 : if (ferror (f))
734 : : {
735 : 20 : display_filename = g_filename_display_name (filename);
736 : 40 : g_set_error (error,
737 : 0 : G_FILE_ERROR,
738 : 20 : g_file_error_from_errno (save_errno),
739 : 0 : _("Error reading file “%s”: %s"),
740 : 0 : display_filename,
741 : 0 : g_strerror (save_errno));
742 : 20 : g_free (display_filename);
743 : :
744 : 20 : goto error;
745 : : }
746 : :
747 : 23496 : g_assert (str != NULL);
748 : 23496 : memcpy (str + total_bytes, buf, bytes);
749 : :
750 : 23496 : total_bytes += bytes;
751 : : }
752 : :
753 : 442 : fclose (f);
754 : :
755 : 442 : if (total_allocated == 0)
756 : : {
757 : 0 : str = g_new (gchar, 1);
758 : 0 : total_bytes = 0;
759 : 0 : }
760 : :
761 : 442 : str[total_bytes] = '\0';
762 : :
763 : 442 : if (length)
764 : 323 : *length = total_bytes;
765 : :
766 : 442 : *contents = str;
767 : :
768 : 442 : return TRUE;
769 : :
770 : 0 : file_too_large:
771 : 0 : display_filename = g_filename_display_name (filename);
772 : 0 : g_set_error (error,
773 : 0 : G_FILE_ERROR,
774 : : G_FILE_ERROR_FAILED,
775 : 0 : _("File “%s” is too large"),
776 : 0 : display_filename);
777 : 0 : g_free (display_filename);
778 : :
779 : 20 : error:
780 : :
781 : 20 : g_free (str);
782 : 20 : fclose (f);
783 : :
784 : 20 : return FALSE;
785 : 432 : }
786 : :
787 : : #ifndef G_OS_WIN32
788 : :
789 : : static gboolean
790 : 869 : get_contents_regfile (const gchar *filename,
791 : : struct stat *stat_buf,
792 : : gint fd,
793 : : gchar **contents,
794 : : gsize *length,
795 : : GError **error)
796 : : {
797 : : gchar *buf;
798 : : gsize bytes_read;
799 : : gsize size;
800 : : gsize alloc_size;
801 : : gchar *display_filename;
802 : :
803 : : if ((G_MAXOFFSET >= G_MAXSIZE) && (stat_buf->st_size > (goffset) (G_MAXSIZE - 1)))
804 : : {
805 : : display_filename = g_filename_display_name (filename);
806 : : g_set_error (error,
807 : : G_FILE_ERROR,
808 : : G_FILE_ERROR_FAILED,
809 : : _("File “%s” is too large"),
810 : : display_filename);
811 : : g_free (display_filename);
812 : : goto error;
813 : : }
814 : :
815 : 869 : size = stat_buf->st_size;
816 : :
817 : 869 : alloc_size = size + 1;
818 : 869 : buf = g_try_malloc (alloc_size);
819 : :
820 : 869 : if (buf == NULL)
821 : : {
822 : 0 : char *display_size = g_format_size_full (alloc_size, G_FORMAT_SIZE_LONG_FORMAT);
823 : 0 : display_filename = g_filename_display_name (filename);
824 : 0 : g_set_error (error,
825 : : G_FILE_ERROR,
826 : : G_FILE_ERROR_NOMEM,
827 : : /* Translators: the first %s contains the file size
828 : : * (already formatted with units), and the second %s
829 : : * contains the file name */
830 : : _("Could not allocate %s to read file “%s”"),
831 : : display_size,
832 : : display_filename);
833 : 0 : g_free (display_filename);
834 : 0 : g_free (display_size);
835 : 0 : goto error;
836 : : }
837 : :
838 : 869 : bytes_read = 0;
839 : 1738 : while (bytes_read < size)
840 : : {
841 : : gssize rc;
842 : :
843 : 869 : rc = read (fd, buf + bytes_read, size - bytes_read);
844 : :
845 : 869 : if (rc < 0)
846 : : {
847 : 0 : if (errno != EINTR)
848 : : {
849 : 0 : int save_errno = errno;
850 : :
851 : 0 : g_free (buf);
852 : 0 : display_filename = g_filename_display_name (filename);
853 : 0 : g_set_error (error,
854 : : G_FILE_ERROR,
855 : 0 : g_file_error_from_errno (save_errno),
856 : : _("Failed to read from file “%s”: %s"),
857 : : display_filename,
858 : : g_strerror (save_errno));
859 : 0 : g_free (display_filename);
860 : 0 : goto error;
861 : : }
862 : : }
863 : 869 : else if (rc == 0)
864 : 0 : break;
865 : : else
866 : 869 : bytes_read += rc;
867 : : }
868 : :
869 : 869 : buf[bytes_read] = '\0';
870 : :
871 : 869 : if (length)
872 : 585 : *length = bytes_read;
873 : :
874 : 869 : *contents = buf;
875 : :
876 : 869 : close (fd);
877 : :
878 : 869 : return TRUE;
879 : :
880 : 0 : error:
881 : :
882 : 0 : close (fd);
883 : :
884 : 0 : return FALSE;
885 : : }
886 : :
887 : : static gboolean
888 : 939 : get_contents_posix (const gchar *filename,
889 : : gchar **contents,
890 : : gsize *length,
891 : : GError **error)
892 : : {
893 : : struct stat stat_buf;
894 : : gint fd;
895 : :
896 : : /* O_BINARY useful on Cygwin */
897 : 939 : fd = open (filename, O_RDONLY | O_BINARY | O_CLOEXEC);
898 : :
899 : 939 : if (fd < 0)
900 : : {
901 : 40 : int saved_errno = errno;
902 : :
903 : 40 : if (error)
904 : 19 : set_file_error (error,
905 : : filename,
906 : : _("Failed to open file “%s”: %s"),
907 : : saved_errno);
908 : :
909 : 40 : return FALSE;
910 : : }
911 : :
912 : : /* I don't think this will ever fail, aside from ENOMEM, but. */
913 : 899 : if (fstat (fd, &stat_buf) < 0)
914 : : {
915 : 0 : int saved_errno = errno;
916 : 0 : if (error)
917 : 0 : set_file_error (error,
918 : : filename,
919 : : _("Failed to get attributes of file “%s”: fstat() failed: %s"),
920 : : saved_errno);
921 : 0 : close (fd);
922 : :
923 : 0 : return FALSE;
924 : : }
925 : :
926 : 899 : if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
927 : : {
928 : 869 : gboolean retval = get_contents_regfile (filename,
929 : : &stat_buf,
930 : : fd,
931 : : contents,
932 : : length,
933 : : error);
934 : :
935 : 869 : return retval;
936 : : }
937 : : else
938 : : {
939 : : FILE *f;
940 : : gboolean retval;
941 : :
942 : 30 : f = fdopen (fd, "re");
943 : :
944 : 30 : if (f == NULL)
945 : : {
946 : 0 : int saved_errno = errno;
947 : 0 : if (error)
948 : 0 : set_file_error (error,
949 : : filename,
950 : : _("Failed to open file “%s”: fdopen() failed: %s"),
951 : : saved_errno);
952 : :
953 : 0 : return FALSE;
954 : : }
955 : :
956 : 30 : retval = get_contents_stdio (filename, f, contents, length, error);
957 : :
958 : 30 : return retval;
959 : : }
960 : : }
961 : :
962 : : #else /* G_OS_WIN32 */
963 : :
964 : : static gboolean
965 : 444 : get_contents_win32 (const gchar *filename,
966 : : gchar **contents,
967 : : gsize *length,
968 : : GError **error)
969 : : {
970 : : FILE *f;
971 : : gboolean retval;
972 : :
973 : 444 : f = g_fopen (filename, "rbe");
974 : :
975 : 444 : if (f == NULL)
976 : : {
977 : 12 : int saved_errno = errno;
978 : 12 : if (error)
979 : 24 : set_file_error (error,
980 : 12 : filename,
981 : 12 : _("Failed to open file “%s”: %s"),
982 : 12 : saved_errno);
983 : :
984 : 12 : return FALSE;
985 : : }
986 : :
987 : 432 : retval = get_contents_stdio (filename, f, contents, length, error);
988 : :
989 : 432 : return retval;
990 : 444 : }
991 : :
992 : : #endif
993 : :
994 : : /**
995 : : * g_file_get_contents:
996 : : * @filename: (type filename): name of a file to read contents from, in the GLib file name encoding
997 : : * @contents: (out) (array length=length) (element-type guint8): location to store an allocated string, use g_free() to free
998 : : * the returned string
999 : : * @length: (nullable): location to store length in bytes of the contents, or %NULL
1000 : : * @error: return location for a #GError, or %NULL
1001 : : *
1002 : : * Reads an entire file into allocated memory, with good error
1003 : : * checking.
1004 : : *
1005 : : * If the call was successful, it returns %TRUE and sets @contents to the file
1006 : : * contents and @length to the length of the file contents in bytes. The string
1007 : : * stored in @contents will be nul-terminated, so for text files you can pass
1008 : : * %NULL for the @length argument. If the call was not successful, it returns
1009 : : * %FALSE and sets @error. The error domain is %G_FILE_ERROR. Possible error
1010 : : * codes are those in the #GFileError enumeration. In the error case,
1011 : : * @contents is set to %NULL and @length is set to zero.
1012 : : *
1013 : : * Returns: %TRUE on success, %FALSE if an error occurred
1014 : : **/
1015 : : gboolean
1016 : 1387 : g_file_get_contents (const gchar *filename,
1017 : : gchar **contents,
1018 : : gsize *length,
1019 : : GError **error)
1020 : : {
1021 : 1387 : g_return_val_if_fail (filename != NULL, FALSE);
1022 : 1385 : g_return_val_if_fail (contents != NULL, FALSE);
1023 : :
1024 : 1383 : *contents = NULL;
1025 : 1383 : if (length)
1026 : 940 : *length = 0;
1027 : :
1028 : : #ifdef G_OS_WIN32
1029 : 444 : return get_contents_win32 (filename, contents, length, error);
1030 : : #else
1031 : 939 : return get_contents_posix (filename, contents, length, error);
1032 : : #endif
1033 : 446 : }
1034 : :
1035 : : static gboolean
1036 : 658 : rename_file (const char *old_name,
1037 : : const char *new_name,
1038 : : gboolean do_fsync,
1039 : : GError **err)
1040 : : {
1041 : 658 : errno = 0;
1042 : 658 : if (g_rename (old_name, new_name) == -1)
1043 : : {
1044 : 12 : int save_errno = errno;
1045 : 12 : gchar *display_old_name = g_filename_display_name (old_name);
1046 : 12 : gchar *display_new_name = g_filename_display_name (new_name);
1047 : :
1048 : 24 : g_set_error (err,
1049 : 6 : G_FILE_ERROR,
1050 : 12 : g_file_error_from_errno (save_errno),
1051 : 6 : _("Failed to rename file “%s” to “%s”: g_rename() failed: %s"),
1052 : 6 : display_old_name,
1053 : 6 : display_new_name,
1054 : 6 : g_strerror (save_errno));
1055 : :
1056 : 12 : g_free (display_old_name);
1057 : 12 : g_free (display_new_name);
1058 : :
1059 : 12 : return FALSE;
1060 : : }
1061 : :
1062 : : /* In order to guarantee that the *new* contents of the file are seen in
1063 : : * future, fsync() the directory containing the file. Otherwise if the file
1064 : : * system was unmounted cleanly now, it would be undefined whether the old
1065 : : * or new contents of the file were visible after recovery.
1066 : : *
1067 : : * This assumes the @old_name and @new_name are in the same directory. */
1068 : : #ifdef HAVE_FSYNC
1069 : 575 : if (do_fsync)
1070 : : {
1071 : 159 : gchar *dir = g_path_get_dirname (new_name);
1072 : 159 : int dir_fd = g_open (dir, O_RDONLY | O_CLOEXEC, 0);
1073 : :
1074 : 159 : if (dir_fd >= 0)
1075 : : {
1076 : 159 : g_fsync (dir_fd);
1077 : 159 : g_close (dir_fd, NULL);
1078 : : }
1079 : :
1080 : 159 : g_free (dir);
1081 : : }
1082 : : #endif /* HAVE_FSYNC */
1083 : :
1084 : 646 : return TRUE;
1085 : 77 : }
1086 : :
1087 : : static gboolean
1088 : 821 : fd_should_be_fsynced (int fd,
1089 : : const gchar *test_file,
1090 : : GFileSetContentsFlags flags)
1091 : : {
1092 : : #ifdef HAVE_FSYNC
1093 : : struct stat statbuf;
1094 : :
1095 : : /* If the final destination exists and is > 0 bytes, we want to sync the
1096 : : * newly written file to ensure the data is on disk when we rename over
1097 : : * the destination. Otherwise if we get a system crash we can lose both
1098 : : * the new and the old file on some filesystems. (I.E. those that don't
1099 : : * guarantee the data is written to the disk before the metadata.)
1100 : : *
1101 : : * There is no difference (in file system terms) if the old file doesn’t
1102 : : * already exist, apart from the fact that if the system crashes and the new
1103 : : * data hasn’t been fsync()ed, there is only one bit of old data to lose (that
1104 : : * the file didn’t exist in the first place). In some situations, such as
1105 : : * trashing files, the old file never exists, so it seems reasonable to avoid
1106 : : * the fsync(). This is not a widely applicable optimisation though.
1107 : : */
1108 : 716 : if ((flags & (G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_DURABLE)) &&
1109 : 595 : (flags & G_FILE_SET_CONTENTS_ONLY_EXISTING))
1110 : : {
1111 : 555 : errno = 0;
1112 : 555 : if (g_lstat (test_file, &statbuf) == 0)
1113 : 193 : return (statbuf.st_size > 0);
1114 : 362 : else if (errno == ENOENT)
1115 : 362 : return FALSE;
1116 : : else
1117 : 0 : return TRUE; /* lstat() failed; be cautious */
1118 : : }
1119 : : else
1120 : : {
1121 : 161 : return (flags & (G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_DURABLE));
1122 : : }
1123 : : #else /* if !HAVE_FSYNC */
1124 : 105 : return FALSE;
1125 : : #endif /* !HAVE_FSYNC */
1126 : : }
1127 : :
1128 : : static gboolean
1129 : 163 : truncate_file (int fd,
1130 : : off_t length,
1131 : : const char *dest_file,
1132 : : GError **error)
1133 : : {
1134 : 163 : while (
1135 : : #ifdef G_OS_WIN32
1136 : 28 : g_win32_ftruncate (fd, length) < 0
1137 : : #else
1138 : 135 : ftruncate (fd, length) < 0
1139 : : #endif
1140 : : )
1141 : : {
1142 : 0 : int saved_errno = errno;
1143 : :
1144 : 0 : if (saved_errno == EINTR)
1145 : 0 : continue;
1146 : :
1147 : 0 : if (error != NULL)
1148 : 0 : set_file_error (error,
1149 : 0 : dest_file,
1150 : 0 : _("Failed to write file “%s”: ftruncate() failed: %s"),
1151 : 0 : saved_errno);
1152 : 0 : return FALSE;
1153 : : }
1154 : :
1155 : 163 : return TRUE;
1156 : 28 : }
1157 : :
1158 : : /* closes @fd once it’s finished (on success or error) */
1159 : : static gboolean
1160 : 821 : write_to_file (const gchar *contents,
1161 : : gsize length,
1162 : : int fd,
1163 : : const gchar *dest_file,
1164 : : gboolean do_fsync,
1165 : : GError **err)
1166 : : {
1167 : : #ifdef HAVE_FALLOCATE
1168 : 716 : if (length > 0)
1169 : : {
1170 : : /* We do this on a 'best effort' basis... It may not be supported
1171 : : * on the underlying filesystem.
1172 : : */
1173 : 677 : (void) fallocate (fd, 0, 0, length);
1174 : : }
1175 : : #endif
1176 : 1595 : while (length > 0)
1177 : : {
1178 : : gssize s;
1179 : :
1180 : : #ifdef G_OS_WIN32
1181 : : /* 'write' on windows uses int types, so limit count to G_MAXINT */
1182 : 97 : s = write (fd, contents, MIN (length, (gsize) G_MAXINT));
1183 : : #else
1184 : : /* Limit count to G_MAXSSIZE to fit into the return value. */
1185 : 677 : s = write (fd, contents, MIN (length, (gsize) G_MAXSSIZE));
1186 : : #endif
1187 : 774 : if (s < 0)
1188 : : {
1189 : 0 : int saved_errno = errno;
1190 : 0 : if (saved_errno == EINTR)
1191 : 0 : continue;
1192 : :
1193 : 0 : if (err)
1194 : 0 : set_file_error (err,
1195 : 0 : dest_file, _("Failed to write file “%s”: write() failed: %s"),
1196 : 0 : saved_errno);
1197 : 0 : close (fd);
1198 : :
1199 : 0 : return FALSE;
1200 : : }
1201 : :
1202 : 774 : g_assert ((gsize) s <= length);
1203 : :
1204 : 774 : contents += s;
1205 : 774 : length -= s;
1206 : : }
1207 : :
1208 : :
1209 : : #ifdef HAVE_FSYNC
1210 : 716 : errno = 0;
1211 : 716 : if (do_fsync && g_fsync (fd) != 0)
1212 : : {
1213 : 0 : int saved_errno = errno;
1214 : 0 : if (err)
1215 : 0 : set_file_error (err,
1216 : : dest_file, _("Failed to write file “%s”: fsync() failed: %s"),
1217 : : saved_errno);
1218 : 0 : close (fd);
1219 : :
1220 : 0 : return FALSE;
1221 : : }
1222 : : #endif
1223 : :
1224 : 821 : errno = 0;
1225 : 821 : if (!g_close (fd, err))
1226 : 0 : return FALSE;
1227 : :
1228 : 821 : return TRUE;
1229 : 105 : }
1230 : :
1231 : : /**
1232 : : * g_file_set_contents:
1233 : : * @filename: (type filename): name of a file to write @contents to, in the GLib file name
1234 : : * encoding
1235 : : * @contents: (array length=length) (element-type guint8): string to write to the file
1236 : : * @length: length of @contents, or -1 if @contents is a nul-terminated string
1237 : : * @error: return location for a #GError, or %NULL
1238 : : *
1239 : : * Writes all of @contents to a file named @filename. This is a convenience
1240 : : * wrapper around calling g_file_set_contents_full() with `flags` set to
1241 : : * `G_FILE_SET_CONTENTS_CONSISTENT | G_FILE_SET_CONTENTS_ONLY_EXISTING` and
1242 : : * `mode` set to `0666`.
1243 : : *
1244 : : * Returns: %TRUE on success, %FALSE if an error occurred
1245 : : *
1246 : : * Since: 2.8
1247 : : */
1248 : : gboolean
1249 : 425 : g_file_set_contents (const gchar *filename,
1250 : : const gchar *contents,
1251 : : gssize length,
1252 : : GError **error)
1253 : : {
1254 : 467 : return g_file_set_contents_full (filename, contents, length,
1255 : : G_FILE_SET_CONTENTS_CONSISTENT |
1256 : : G_FILE_SET_CONTENTS_ONLY_EXISTING,
1257 : 42 : 0666, error);
1258 : : }
1259 : :
1260 : : /**
1261 : : * g_file_set_contents_full:
1262 : : * @filename: (type filename): name of a file to write @contents to, in the GLib file name
1263 : : * encoding
1264 : : * @contents: (array length=length) (element-type guint8): string to write to the file
1265 : : * @length: length of @contents, or -1 if @contents is a nul-terminated string
1266 : : * @flags: flags controlling the safety vs speed of the operation
1267 : : * @mode: file mode, as passed to `open()`; typically this will be `0666`
1268 : : * @error: return location for a #GError, or %NULL
1269 : : *
1270 : : * Writes all of @contents to a file named @filename, with good error checking.
1271 : : * If a file called @filename already exists it will be overwritten.
1272 : : *
1273 : : * @flags control the properties of the write operation: whether it’s atomic,
1274 : : * and what the tradeoff is between returning quickly or being resilient to
1275 : : * system crashes.
1276 : : *
1277 : : * As this function performs file I/O, it is recommended to not call it anywhere
1278 : : * where blocking would cause problems, such as in the main loop of a graphical
1279 : : * application. In particular, if @flags has any value other than
1280 : : * %G_FILE_SET_CONTENTS_NONE then this function may call `fsync()`.
1281 : : *
1282 : : * If %G_FILE_SET_CONTENTS_CONSISTENT is set in @flags, the operation is atomic
1283 : : * in the sense that it is first written to a temporary file which is then
1284 : : * renamed to the final name.
1285 : : *
1286 : : * Notes:
1287 : : *
1288 : : * - On UNIX, if @filename already exists hard links to @filename will break.
1289 : : * Also since the file is recreated, existing permissions, access control
1290 : : * lists, metadata etc. may be lost. If @filename is a symbolic link,
1291 : : * the link itself will be replaced, not the linked file.
1292 : : *
1293 : : * - On UNIX, if @filename already exists and is non-empty, and if the system
1294 : : * supports it (via a journalling filesystem or equivalent), and if
1295 : : * %G_FILE_SET_CONTENTS_CONSISTENT is set in @flags, the `fsync()` call (or
1296 : : * equivalent) will be used to ensure atomic replacement: @filename
1297 : : * will contain either its old contents or @contents, even in the face of
1298 : : * system power loss, the disk being unsafely removed, etc.
1299 : : *
1300 : : * - On UNIX, if @filename does not already exist or is empty, there is a
1301 : : * possibility that system power loss etc. after calling this function will
1302 : : * leave @filename empty or full of NUL bytes, depending on the underlying
1303 : : * filesystem, unless %G_FILE_SET_CONTENTS_DURABLE and
1304 : : * %G_FILE_SET_CONTENTS_CONSISTENT are set in @flags.
1305 : : *
1306 : : * - On Windows renaming a file will not remove an existing file with the
1307 : : * new name, so on Windows there is a race condition between the existing
1308 : : * file being removed and the temporary file being renamed.
1309 : : *
1310 : : * - On Windows there is no way to remove a file that is open to some
1311 : : * process, or mapped into memory. Thus, this function will fail if
1312 : : * @filename already exists and is open.
1313 : : *
1314 : : * If the call was successful, it returns %TRUE. If the call was not successful,
1315 : : * it returns %FALSE and sets @error. The error domain is %G_FILE_ERROR.
1316 : : * Possible error codes are those in the #GFileError enumeration.
1317 : : *
1318 : : * Note that the name for the temporary file is constructed by appending up
1319 : : * to 7 characters to @filename.
1320 : : *
1321 : : * If the file didn’t exist before and is created, it will be given the
1322 : : * permissions from @mode. Otherwise, the permissions of the existing file will
1323 : : * remain unchanged.
1324 : : *
1325 : : * Returns: %TRUE on success, %FALSE if an error occurred
1326 : : *
1327 : : * Since: 2.66
1328 : : */
1329 : : gboolean
1330 : 859 : g_file_set_contents_full (const gchar *filename,
1331 : : const gchar *contents,
1332 : : gssize length,
1333 : : GFileSetContentsFlags flags,
1334 : : int mode,
1335 : : GError **error)
1336 : : {
1337 : 859 : g_return_val_if_fail (filename != NULL, FALSE);
1338 : 857 : g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1339 : 857 : g_return_val_if_fail (contents != NULL || length == 0, FALSE);
1340 : 855 : g_return_val_if_fail (length >= -1, FALSE);
1341 : :
1342 : : /* @flags are handled as follows:
1343 : : * - %G_FILE_SET_CONTENTS_NONE: write directly to @filename, no fsync()s
1344 : : * - %G_FILE_SET_CONTENTS_CONSISTENT: write to temp file, fsync() it, rename()
1345 : : * - %G_FILE_SET_CONTENTS_CONSISTENT | ONLY_EXISTING: as above, but skip the
1346 : : * fsync() if @filename doesn’t exist or is empty
1347 : : * - %G_FILE_SET_CONTENTS_DURABLE: write directly to @filename, fsync() it
1348 : : * - %G_FILE_SET_CONTENTS_DURABLE | ONLY_EXISTING: as above, but skip the
1349 : : * fsync() if @filename doesn’t exist or is empty
1350 : : * - %G_FILE_SET_CONTENTS_CONSISTENT | DURABLE: write to temp file, fsync()
1351 : : * it, rename(), fsync() containing directory
1352 : : * - %G_FILE_SET_CONTENTS_CONSISTENT | DURABLE | ONLY_EXISTING: as above, but
1353 : : * skip both fsync()s if @filename doesn’t exist or is empty
1354 : : */
1355 : :
1356 : 855 : if (length < 0)
1357 : 413 : length = strlen (contents);
1358 : :
1359 : 855 : if (flags & G_FILE_SET_CONTENTS_CONSISTENT)
1360 : : {
1361 : 662 : gchar *tmp_filename = NULL;
1362 : 662 : GError *rename_error = NULL;
1363 : : gboolean retval;
1364 : : int fd;
1365 : : gboolean do_fsync;
1366 : : GStatBuf old_stat;
1367 : :
1368 : 662 : tmp_filename = g_strdup_printf ("%s.XXXXXX", filename);
1369 : :
1370 : 662 : errno = 0;
1371 : 662 : fd = g_mkstemp_full (tmp_filename, O_RDWR | O_BINARY | O_CLOEXEC, mode);
1372 : :
1373 : 662 : if (fd == -1)
1374 : : {
1375 : 4 : int saved_errno = errno;
1376 : 4 : if (error)
1377 : 4 : set_file_error (error,
1378 : 0 : tmp_filename, _("Failed to create file “%s”: %s"),
1379 : 0 : saved_errno);
1380 : 4 : retval = FALSE;
1381 : 4 : goto consistent_out;
1382 : : }
1383 : :
1384 : : /* Maintain the permissions of the file if it exists */
1385 : 658 : if (!g_stat (filename, &old_stat))
1386 : : {
1387 : : #ifndef G_OS_WIN32
1388 : 206 : if (fchmod (fd, old_stat.st_mode))
1389 : : #else /* G_OS_WIN32 */
1390 : 41 : if (g_chmod (tmp_filename, old_stat.st_mode))
1391 : : #endif /* G_OS_WIN32 */
1392 : : {
1393 : 0 : int saved_errno = errno;
1394 : 0 : if (error)
1395 : 0 : set_file_error (error,
1396 : 0 : tmp_filename, _ ("Failed to set permissions of “%s”: %s"),
1397 : 0 : saved_errno);
1398 : 0 : g_unlink (tmp_filename);
1399 : 0 : retval = FALSE;
1400 : 0 : goto consistent_out;
1401 : : }
1402 : 41 : }
1403 : :
1404 : 658 : do_fsync = fd_should_be_fsynced (fd, filename, flags);
1405 : 658 : if (!write_to_file (contents, length, g_steal_fd (&fd), tmp_filename, do_fsync, error))
1406 : : {
1407 : 0 : g_unlink (tmp_filename);
1408 : 0 : retval = FALSE;
1409 : 0 : goto consistent_out;
1410 : : }
1411 : :
1412 : 658 : if (!rename_file (tmp_filename, filename, do_fsync, &rename_error))
1413 : : {
1414 : : #ifndef G_OS_WIN32
1415 : :
1416 : 6 : g_unlink (tmp_filename);
1417 : 6 : g_propagate_error (error, rename_error);
1418 : 6 : retval = FALSE;
1419 : 6 : goto consistent_out;
1420 : :
1421 : : #else /* G_OS_WIN32 */
1422 : :
1423 : : /* Renaming failed, but on Windows this may just mean
1424 : : * the file already exists. So if the target file
1425 : : * exists, try deleting it and do the rename again.
1426 : : */
1427 : 6 : if (!g_file_test (filename, G_FILE_TEST_EXISTS))
1428 : : {
1429 : 0 : g_unlink (tmp_filename);
1430 : 0 : g_propagate_error (error, rename_error);
1431 : 0 : retval = FALSE;
1432 : 0 : goto consistent_out;
1433 : : }
1434 : :
1435 : 6 : g_error_free (rename_error);
1436 : :
1437 : 6 : if (g_unlink (filename) == -1)
1438 : : {
1439 : 6 : int saved_errno = errno;
1440 : 6 : if (error)
1441 : 12 : set_file_error (error,
1442 : 6 : filename,
1443 : 6 : _("Existing file “%s” could not be removed: g_unlink() failed: %s"),
1444 : 6 : saved_errno);
1445 : 6 : g_unlink (tmp_filename);
1446 : 6 : retval = FALSE;
1447 : 6 : goto consistent_out;
1448 : : }
1449 : :
1450 : 0 : if (!rename_file (tmp_filename, filename, flags, error))
1451 : : {
1452 : 0 : g_unlink (tmp_filename);
1453 : 0 : retval = FALSE;
1454 : 0 : goto consistent_out;
1455 : : }
1456 : :
1457 : : #endif /* G_OS_WIN32 */
1458 : 0 : }
1459 : :
1460 : 646 : retval = TRUE;
1461 : :
1462 : 585 : consistent_out:
1463 : 662 : g_free (tmp_filename);
1464 : 662 : return retval;
1465 : : }
1466 : : else
1467 : : {
1468 : : int direct_fd;
1469 : : int open_flags;
1470 : : gboolean do_fsync;
1471 : :
1472 : 193 : open_flags = O_RDWR | O_BINARY | O_CREAT | O_CLOEXEC;
1473 : : #ifdef O_NOFOLLOW
1474 : : /* Windows doesn’t have symlinks, so O_NOFOLLOW is unnecessary there. */
1475 : 156 : open_flags |= O_NOFOLLOW;
1476 : : #endif
1477 : :
1478 : 193 : errno = 0;
1479 : 193 : direct_fd = g_open (filename, open_flags, mode);
1480 : :
1481 : 193 : if (direct_fd < 0)
1482 : : {
1483 : 30 : int saved_errno = errno;
1484 : :
1485 : : #ifdef O_NOFOLLOW
1486 : : /* ELOOP indicates that @filename is a symlink, since we used
1487 : : * O_NOFOLLOW (alternately it could indicate that @filename contains
1488 : : * looping or too many symlinks). In either case, try again on the
1489 : : * %G_FILE_SET_CONTENTS_CONSISTENT code path.
1490 : : *
1491 : : * FreeBSD uses EMLINK instead of ELOOP
1492 : : * (https://www.freebsd.org/cgi/man.cgi?query=open&sektion=2#STANDARDS),
1493 : : * and NetBSD uses EFTYPE
1494 : : * (https://netbsd.gw.com/cgi-bin/man-cgi?open+2+NetBSD-current). */
1495 : : #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
1496 : : if (saved_errno == EMLINK)
1497 : : #elif defined(__NetBSD__)
1498 : : if (saved_errno == EFTYPE)
1499 : : #else
1500 : 21 : if (saved_errno == ELOOP)
1501 : : #endif
1502 : 21 : return g_file_set_contents_full (filename, contents, length,
1503 : 8 : flags | G_FILE_SET_CONTENTS_CONSISTENT,
1504 : : mode, error);
1505 : : #endif /* O_NOFOLLOW */
1506 : :
1507 : 22 : if (error)
1508 : 31 : set_file_error (error,
1509 : 9 : filename, _("Failed to open file “%s”: %s"),
1510 : 9 : saved_errno);
1511 : 22 : return FALSE;
1512 : : }
1513 : :
1514 : 163 : do_fsync = fd_should_be_fsynced (direct_fd, filename, flags);
1515 : 163 : if (!truncate_file (direct_fd, 0, filename, error))
1516 : 0 : return FALSE;
1517 : 191 : if (!write_to_file (contents, length, g_steal_fd (&direct_fd), filename,
1518 : 28 : do_fsync, error))
1519 : 0 : return FALSE;
1520 : : }
1521 : :
1522 : 163 : return TRUE;
1523 : 116 : }
1524 : :
1525 : : /*
1526 : : * get_tmp_file based on the mkstemp implementation from the GNU C library.
1527 : : * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
1528 : : */
1529 : : typedef gint (*GTmpFileCallback) (const gchar *, gint, gint);
1530 : :
1531 : : static gint
1532 : 1545 : get_tmp_file (gchar *tmpl,
1533 : : GTmpFileCallback f,
1534 : : int flags,
1535 : : int mode)
1536 : : {
1537 : : char *XXXXXX;
1538 : : int count, fd;
1539 : : static const char letters[] =
1540 : : "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
1541 : : static const int NLETTERS = sizeof (letters) - 1;
1542 : : guint64 value;
1543 : : guint64 now_us;
1544 : : static guint counter = 0;
1545 : :
1546 : 1545 : g_return_val_if_fail (tmpl != NULL, -1);
1547 : :
1548 : : /* find the last occurrence of "XXXXXX" */
1549 : 1543 : XXXXXX = g_strrstr (tmpl, "XXXXXX");
1550 : :
1551 : 1543 : if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
1552 : : {
1553 : 12 : errno = EINVAL;
1554 : 12 : return -1;
1555 : : }
1556 : :
1557 : : /* Get some more or less random data. */
1558 : 1531 : now_us = g_get_real_time ();
1559 : 1531 : value = ((now_us % G_USEC_PER_SEC) ^ (now_us / G_USEC_PER_SEC)) + counter++;
1560 : :
1561 : 1531 : for (count = 0; count < 100; value += 7777, ++count)
1562 : : {
1563 : 1531 : guint64 v = value;
1564 : :
1565 : : /* Fill in the random bits. */
1566 : 1531 : XXXXXX[0] = letters[v % NLETTERS];
1567 : 1531 : v /= NLETTERS;
1568 : 1531 : XXXXXX[1] = letters[v % NLETTERS];
1569 : 1531 : v /= NLETTERS;
1570 : 1531 : XXXXXX[2] = letters[v % NLETTERS];
1571 : 1531 : v /= NLETTERS;
1572 : 1531 : XXXXXX[3] = letters[v % NLETTERS];
1573 : 1531 : v /= NLETTERS;
1574 : 1531 : XXXXXX[4] = letters[v % NLETTERS];
1575 : 1531 : v /= NLETTERS;
1576 : 1531 : XXXXXX[5] = letters[v % NLETTERS];
1577 : :
1578 : 1531 : fd = f (tmpl, flags, mode);
1579 : :
1580 : 1531 : if (fd >= 0)
1581 : 1523 : return fd;
1582 : 8 : else if (errno != EEXIST)
1583 : : /* Any other error will apply also to other names we might
1584 : : * try, and there are 2^32 or so of them, so give up now.
1585 : : */
1586 : 8 : return -1;
1587 : 0 : }
1588 : :
1589 : : /* We got out of the loop because we ran out of combinations to try. */
1590 : 0 : errno = EEXIST;
1591 : 0 : return -1;
1592 : 248 : }
1593 : :
1594 : : /* Some GTmpFileCallback implementations.
1595 : : *
1596 : : * Note: we cannot use open() or g_open() directly because even though
1597 : : * they appear compatible, they may be vararg functions and calling
1598 : : * varargs functions through a non-varargs type is undefined.
1599 : : */
1600 : : static gint
1601 : 396 : wrap_g_mkdir (const gchar *filename,
1602 : : int flags G_GNUC_UNUSED,
1603 : : int mode)
1604 : : {
1605 : : /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */
1606 : 396 : return g_mkdir (filename, mode);
1607 : : }
1608 : :
1609 : : static gint
1610 : 1135 : wrap_g_open (const gchar *filename,
1611 : : int flags,
1612 : : int mode)
1613 : : {
1614 : 1135 : return g_open (filename, flags, mode);
1615 : : }
1616 : :
1617 : : /**
1618 : : * g_mkdtemp_full: (skip)
1619 : : * @tmpl: (type filename): template directory name
1620 : : * @mode: permissions to create the temporary directory with
1621 : : *
1622 : : * Creates a temporary directory in the current directory.
1623 : : *
1624 : : * See the [`mkdtemp()`](man:mkdtemp(3)) documentation on most UNIX-like systems.
1625 : : *
1626 : : * The parameter is a string that should follow the rules for
1627 : : * mkdtemp() templates, i.e. contain the string "XXXXXX".
1628 : : * g_mkdtemp_full() is slightly more flexible than mkdtemp() in that the
1629 : : * sequence does not have to occur at the very end of the template
1630 : : * and you can pass a @mode. The X string will be modified to form
1631 : : * the name of a directory that didn't exist. The string should be
1632 : : * in the GLib file name encoding. Most importantly, on Windows it
1633 : : * should be in UTF-8.
1634 : : *
1635 : : * If you are going to be creating a temporary directory inside the
1636 : : * directory returned by g_get_tmp_dir(), you might want to use
1637 : : * g_dir_make_tmp() instead.
1638 : : *
1639 : : * Returns: (nullable) (type filename): A pointer to @tmpl, which has been
1640 : : * modified to hold the directory name. In case of errors, %NULL is
1641 : : * returned, and %errno will be set.
1642 : : *
1643 : : * Since: 2.30
1644 : : */
1645 : : gchar *
1646 : 13 : g_mkdtemp_full (gchar *tmpl,
1647 : : gint mode)
1648 : : {
1649 : 13 : if (get_tmp_file (tmpl, wrap_g_mkdir, 0, mode) == -1)
1650 : 6 : return NULL;
1651 : : else
1652 : 7 : return tmpl;
1653 : 6 : }
1654 : :
1655 : : /**
1656 : : * g_mkdtemp: (skip)
1657 : : * @tmpl: (type filename): template directory name
1658 : : *
1659 : : * Creates a temporary directory in the current directory.
1660 : : *
1661 : : * See the [`mkdtemp()`](man:mkdtemp(3)) documentation on most UNIX-like systems.
1662 : : *
1663 : : * The parameter is a string that should follow the rules for
1664 : : * mkdtemp() templates, i.e. contain the string "XXXXXX".
1665 : : * g_mkdtemp() is slightly more flexible than mkdtemp() in that the
1666 : : * sequence does not have to occur at the very end of the template.
1667 : : * The X string will be modified to form the name of a directory that
1668 : : * didn't exist.
1669 : : * The string should be in the GLib file name encoding. Most importantly,
1670 : : * on Windows it should be in UTF-8.
1671 : : *
1672 : : * If you are going to be creating a temporary directory inside the
1673 : : * directory returned by g_get_tmp_dir(), you might want to use
1674 : : * g_dir_make_tmp() instead.
1675 : : *
1676 : : * Returns: (nullable) (type filename): A pointer to @tmpl, which has been
1677 : : * modified to hold the directory name. In case of errors, %NULL is
1678 : : * returned and %errno will be set.
1679 : : *
1680 : : * Since: 2.30
1681 : : */
1682 : : gchar *
1683 : 12 : g_mkdtemp (gchar *tmpl)
1684 : : {
1685 : 12 : return g_mkdtemp_full (tmpl, 0700);
1686 : : }
1687 : :
1688 : : /**
1689 : : * g_mkstemp_full: (skip)
1690 : : * @tmpl: (type filename): template filename
1691 : : * @flags: flags to pass to an open() call in addition to O_EXCL
1692 : : * and O_CREAT, which are passed automatically
1693 : : * @mode: permissions to create the temporary file with
1694 : : *
1695 : : * Opens a temporary file in the current directory.
1696 : : *
1697 : : * See the [`mkstemp()`](man:mkstemp(3)) documentation on most UNIX-like systems.
1698 : : *
1699 : : * The parameter is a string that should follow the rules for
1700 : : * mkstemp() templates, i.e. contain the string "XXXXXX".
1701 : : * g_mkstemp_full() is slightly more flexible than mkstemp()
1702 : : * in that the sequence does not have to occur at the very end of the
1703 : : * template and you can pass a @mode and additional @flags. The X
1704 : : * string will be modified to form the name of a file that didn't exist.
1705 : : * The string should be in the GLib file name encoding. Most importantly,
1706 : : * on Windows it should be in UTF-8.
1707 : : *
1708 : : * Returns: A file handle (as from open()) to the file
1709 : : * opened for reading and writing. The file handle should be
1710 : : * closed with close(). In case of errors, -1 is returned
1711 : : * and %errno will be set.
1712 : : *
1713 : : * Since: 2.22
1714 : : */
1715 : : gint
1716 : 820 : g_mkstemp_full (gchar *tmpl,
1717 : : gint flags,
1718 : : gint mode)
1719 : : {
1720 : : /* tmpl is in UTF-8 on Windows, thus use g_open() */
1721 : 914 : return get_tmp_file (tmpl, wrap_g_open,
1722 : 94 : flags | O_CREAT | O_EXCL, mode);
1723 : : }
1724 : :
1725 : : /**
1726 : : * g_mkstemp: (skip)
1727 : : * @tmpl: (type filename): template filename
1728 : : *
1729 : : * Opens a temporary file in the current directory.
1730 : : *
1731 : : * See the [`mkstemp()`](man:mkstemp(3)) documentation on most UNIX-like systems.
1732 : : *
1733 : : * The parameter is a string that should follow the rules for
1734 : : * mkstemp() templates, i.e. contain the string "XXXXXX".
1735 : : * g_mkstemp() is slightly more flexible than mkstemp() in that the
1736 : : * sequence does not have to occur at the very end of the template.
1737 : : * The X string will be modified to form the name of a file that
1738 : : * didn't exist. The string should be in the GLib file name encoding.
1739 : : * Most importantly, on Windows it should be in UTF-8.
1740 : : *
1741 : : * Returns: A file handle (as from open()) to the file
1742 : : * opened for reading and writing. The file is opened in binary
1743 : : * mode on platforms where there is a difference. The file handle
1744 : : * should be closed with close(). In case of errors, -1 is
1745 : : * returned and %errno will be set.
1746 : : */
1747 : : gint
1748 : 64 : g_mkstemp (gchar *tmpl)
1749 : : {
1750 : 64 : return g_mkstemp_full (tmpl, O_RDWR | O_BINARY | O_CLOEXEC, 0600);
1751 : : }
1752 : :
1753 : : static gint
1754 : 725 : g_get_tmp_name (const gchar *tmpl,
1755 : : gchar **name_used,
1756 : : GTmpFileCallback f,
1757 : : gint flags,
1758 : : gint mode,
1759 : : GError **error)
1760 : : {
1761 : : int retval;
1762 : : const char *tmpdir;
1763 : : const char *sep;
1764 : : char *fulltemplate;
1765 : : const char *slash;
1766 : :
1767 : 725 : if (tmpl == NULL)
1768 : 70 : tmpl = ".XXXXXX";
1769 : :
1770 : 725 : if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
1771 : : #ifdef G_OS_WIN32
1772 : 154 : || (strchr (tmpl, '/') != NULL && (slash = "/"))
1773 : : #endif
1774 : : )
1775 : : {
1776 : 7 : gchar *display_tmpl = g_filename_display_name (tmpl);
1777 : : char c[2];
1778 : 7 : c[0] = *slash;
1779 : 7 : c[1] = '\0';
1780 : :
1781 : 11 : g_set_error (error,
1782 : 4 : G_FILE_ERROR,
1783 : : G_FILE_ERROR_FAILED,
1784 : 4 : _("Template “%s” invalid, should not contain a “%s”"),
1785 : 4 : display_tmpl, c);
1786 : 7 : g_free (display_tmpl);
1787 : :
1788 : 7 : return -1;
1789 : : }
1790 : :
1791 : 718 : if (strstr (tmpl, "XXXXXX") == NULL)
1792 : : {
1793 : 6 : gchar *display_tmpl = g_filename_display_name (tmpl);
1794 : 8 : g_set_error (error,
1795 : 2 : G_FILE_ERROR,
1796 : : G_FILE_ERROR_FAILED,
1797 : 2 : _("Template “%s” doesn’t contain XXXXXX"),
1798 : 2 : display_tmpl);
1799 : 6 : g_free (display_tmpl);
1800 : 6 : return -1;
1801 : : }
1802 : :
1803 : 712 : tmpdir = g_get_tmp_dir ();
1804 : :
1805 : 712 : if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
1806 : 0 : sep = "";
1807 : : else
1808 : 712 : sep = G_DIR_SEPARATOR_S;
1809 : :
1810 : 712 : fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
1811 : :
1812 : 712 : retval = get_tmp_file (fulltemplate, f, flags, mode);
1813 : 712 : if (retval == -1)
1814 : : {
1815 : 0 : int saved_errno = errno;
1816 : 0 : if (error)
1817 : 0 : set_file_error (error,
1818 : 0 : fulltemplate,
1819 : 0 : _("Failed to create file “%s”: %s"),
1820 : 0 : saved_errno);
1821 : 0 : g_free (fulltemplate);
1822 : 0 : return -1;
1823 : : }
1824 : :
1825 : 712 : *name_used = fulltemplate;
1826 : :
1827 : 712 : return retval;
1828 : 154 : }
1829 : :
1830 : : /**
1831 : : * g_file_open_tmp:
1832 : : * @tmpl: (type filename) (nullable): Template for file name, as in
1833 : : * g_mkstemp(), basename only, or %NULL for a default template
1834 : : * @name_used: (out) (type filename): location to store actual name used,
1835 : : * or %NULL
1836 : : * @error: return location for a #GError
1837 : : *
1838 : : * Opens a file for writing in the preferred directory for temporary
1839 : : * files (as returned by g_get_tmp_dir()).
1840 : : *
1841 : : * @tmpl should be a string in the GLib file name encoding containing
1842 : : * a sequence of six 'X' characters, as the parameter to g_mkstemp().
1843 : : * However, unlike these functions, the template should only be a
1844 : : * basename, no directory components are allowed. If template is
1845 : : * %NULL, a default template is used.
1846 : : *
1847 : : * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not
1848 : : * modified, and might thus be a read-only literal string.
1849 : : *
1850 : : * Upon success, and if @name_used is non-%NULL, the actual name used
1851 : : * is returned in @name_used. This string should be freed with g_free()
1852 : : * when not needed any longer. The returned name is in the GLib file
1853 : : * name encoding.
1854 : : *
1855 : : * Returns: A file handle (as from open()) to the file opened for
1856 : : * reading and writing. The file is opened in binary mode on platforms
1857 : : * where there is a difference. The file handle should be closed with
1858 : : * close(). In case of errors, -1 is returned and @error will be set.
1859 : : */
1860 : : gint
1861 : 331 : g_file_open_tmp (const gchar *tmpl,
1862 : : gchar **name_used,
1863 : : GError **error)
1864 : : {
1865 : : gchar *fulltemplate;
1866 : : gint result;
1867 : :
1868 : 331 : g_return_val_if_fail (error == NULL || *error == NULL, -1);
1869 : :
1870 : 410 : result = g_get_tmp_name (tmpl, &fulltemplate,
1871 : : wrap_g_open,
1872 : : O_CREAT | O_EXCL | O_RDWR | O_BINARY | O_CLOEXEC,
1873 : : 0600,
1874 : 79 : error);
1875 : 331 : if (result != -1)
1876 : : {
1877 : 323 : if (name_used)
1878 : 321 : *name_used = fulltemplate;
1879 : : else
1880 : 2 : g_free (fulltemplate);
1881 : 75 : }
1882 : :
1883 : 331 : return result;
1884 : 79 : }
1885 : :
1886 : : /**
1887 : : * g_dir_make_tmp:
1888 : : * @tmpl: (type filename) (nullable): Template for directory name,
1889 : : * as in g_mkdtemp(), basename only, or %NULL for a default template
1890 : : * @error: return location for a #GError
1891 : : *
1892 : : * Creates a subdirectory in the preferred directory for temporary
1893 : : * files (as returned by g_get_tmp_dir()).
1894 : : *
1895 : : * @tmpl should be a string in the GLib file name encoding containing
1896 : : * a sequence of six 'X' characters, as the parameter to g_mkstemp().
1897 : : * However, unlike these functions, the template should only be a
1898 : : * basename, no directory components are allowed. If template is
1899 : : * %NULL, a default template is used.
1900 : : *
1901 : : * Note that in contrast to g_mkdtemp() (and mkdtemp()) @tmpl is not
1902 : : * modified, and might thus be a read-only literal string.
1903 : : *
1904 : : * Returns: (type filename) (transfer full): The actual name used. This string
1905 : : * should be freed with g_free() when not needed any longer and is
1906 : : * is in the GLib file name encoding. In case of errors, %NULL is
1907 : : * returned and @error will be set.
1908 : : *
1909 : : * Since: 2.30
1910 : : */
1911 : : gchar *
1912 : 394 : g_dir_make_tmp (const gchar *tmpl,
1913 : : GError **error)
1914 : : {
1915 : : gchar *fulltemplate;
1916 : :
1917 : 394 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
1918 : :
1919 : 394 : if (g_get_tmp_name (tmpl, &fulltemplate, wrap_g_mkdir, 0, 0700, error) == -1)
1920 : 5 : return NULL;
1921 : : else
1922 : 389 : return fulltemplate;
1923 : 75 : }
1924 : :
1925 : : static gchar *
1926 : 109299 : g_build_path_va (const gchar *separator,
1927 : : const gchar *first_element,
1928 : : va_list *args,
1929 : : gchar **str_array)
1930 : : {
1931 : : GString *result;
1932 : 109299 : size_t separator_len = strlen (separator);
1933 : 109299 : gboolean is_first = TRUE;
1934 : 109299 : gboolean have_leading = FALSE;
1935 : 109299 : const gchar *single_element = NULL;
1936 : : const gchar *next_element;
1937 : 109299 : const gchar *last_trailing = NULL;
1938 : 109299 : size_t i = 0;
1939 : :
1940 : 109299 : result = g_string_new (NULL);
1941 : :
1942 : 109299 : if (str_array)
1943 : 973 : next_element = str_array[i++];
1944 : : else
1945 : 108326 : next_element = first_element;
1946 : :
1947 : 98642 : while (TRUE)
1948 : 154284 : {
1949 : : const gchar *element;
1950 : : const gchar *start;
1951 : : const gchar *end;
1952 : :
1953 : 331041 : if (next_element)
1954 : : {
1955 : 221742 : element = next_element;
1956 : 221742 : if (str_array)
1957 : 2384 : next_element = str_array[i++];
1958 : : else
1959 : 219358 : next_element = va_arg (*args, gchar *);
1960 : 67458 : }
1961 : : else
1962 : 109299 : break;
1963 : :
1964 : : /* Ignore empty elements */
1965 : 221742 : if (!*element)
1966 : 3559 : continue;
1967 : :
1968 : 218183 : start = element;
1969 : :
1970 : 218183 : if (separator_len)
1971 : : {
1972 : 283478 : while (strncmp (start, separator, separator_len) == 0)
1973 : 65319 : start += separator_len;
1974 : 65739 : }
1975 : :
1976 : 218183 : end = start + strlen (start);
1977 : :
1978 : 218183 : if (separator_len)
1979 : : {
1980 : 282997 : while (end >= start + separator_len &&
1981 : 215844 : strncmp (end - separator_len, separator, separator_len) == 0)
1982 : 227 : end -= separator_len;
1983 : :
1984 : 218159 : last_trailing = end;
1985 : 286292 : while (last_trailing >= element + separator_len &&
1986 : 218097 : strncmp (last_trailing - separator_len, separator, separator_len) == 0)
1987 : 2428 : last_trailing -= separator_len;
1988 : :
1989 : 218159 : if (!have_leading)
1990 : : {
1991 : : /* If the leading and trailing separator strings are in the
1992 : : * same element and overlap, the result is exactly that element
1993 : : */
1994 : 107936 : if (last_trailing <= start)
1995 : 2353 : single_element = element;
1996 : :
1997 : 107936 : g_string_append_len (result, element, start - element);
1998 : 107936 : have_leading = TRUE;
1999 : 33413 : }
2000 : : else
2001 : 110223 : single_element = NULL;
2002 : 65739 : }
2003 : :
2004 : 218183 : if (end == start)
2005 : 2390 : continue;
2006 : :
2007 : 215793 : if (!is_first)
2008 : 31206 : g_string_append (result, separator);
2009 : :
2010 : 215793 : g_string_append_len (result, start, end - start);
2011 : 215793 : is_first = FALSE;
2012 : : }
2013 : :
2014 : 109299 : if (single_element)
2015 : : {
2016 : 16 : g_string_free (result, TRUE);
2017 : 16 : return g_strdup (single_element);
2018 : : }
2019 : : else
2020 : : {
2021 : 109283 : if (last_trailing)
2022 : 33407 : g_string_append (result, last_trailing);
2023 : :
2024 : 109283 : return g_string_free (result, FALSE);
2025 : : }
2026 : 34021 : }
2027 : :
2028 : : /**
2029 : : * g_build_pathv:
2030 : : * @separator: a string used to separate the elements of the path.
2031 : : * @args: (array zero-terminated=1) (element-type filename): %NULL-terminated
2032 : : * array of strings containing the path elements.
2033 : : *
2034 : : * Behaves exactly like g_build_path(), but takes the path elements
2035 : : * as a string array, instead of variadic arguments.
2036 : : *
2037 : : * This function is mainly meant for language bindings.
2038 : : *
2039 : : * Returns: (type filename) (transfer full): a newly-allocated string that
2040 : : * must be freed with g_free().
2041 : : *
2042 : : * Since: 2.8
2043 : : */
2044 : : gchar *
2045 : 112 : g_build_pathv (const gchar *separator,
2046 : : gchar **args)
2047 : : {
2048 : 112 : if (!args)
2049 : 2 : return NULL;
2050 : :
2051 : 110 : return g_build_path_va (separator, NULL, NULL, args);
2052 : 56 : }
2053 : :
2054 : :
2055 : : /**
2056 : : * g_build_path:
2057 : : * @separator: (type filename): a string used to separate the elements of the path.
2058 : : * @first_element: (type filename): the first element in the path
2059 : : * @...: remaining elements in path, terminated by %NULL
2060 : : *
2061 : : * Creates a path from a series of elements using @separator as the
2062 : : * separator between elements.
2063 : : *
2064 : : * At the boundary between two elements, any trailing occurrences of
2065 : : * separator in the first element, or leading occurrences of separator
2066 : : * in the second element are removed and exactly one copy of the
2067 : : * separator is inserted.
2068 : : *
2069 : : * Empty elements are ignored.
2070 : : *
2071 : : * The number of leading copies of the separator on the result is
2072 : : * the same as the number of leading copies of the separator on
2073 : : * the first non-empty element.
2074 : : *
2075 : : * The number of trailing copies of the separator on the result is
2076 : : * the same as the number of trailing copies of the separator on
2077 : : * the last non-empty element. (Determination of the number of
2078 : : * trailing copies is done without stripping leading copies, so
2079 : : * if the separator is `ABA`, then `ABABA` has 1 trailing copy.)
2080 : : *
2081 : : * However, if there is only a single non-empty element, and there
2082 : : * are no characters in that element not part of the leading or
2083 : : * trailing separators, then the result is exactly the original value
2084 : : * of that element.
2085 : : *
2086 : : * Other than for determination of the number of leading and trailing
2087 : : * copies of the separator, elements consisting only of copies
2088 : : * of the separator are ignored.
2089 : : *
2090 : : * Returns: (type filename) (transfer full): the newly allocated path
2091 : : **/
2092 : : gchar *
2093 : 86643 : g_build_path (const gchar *separator,
2094 : : const gchar *first_element,
2095 : : ...)
2096 : : {
2097 : : gchar *str;
2098 : : va_list args;
2099 : :
2100 : 86643 : g_return_val_if_fail (separator != NULL, NULL);
2101 : :
2102 : 86641 : va_start (args, first_element);
2103 : 86641 : str = g_build_path_va (separator, first_element, &args, NULL);
2104 : 86641 : va_end (args);
2105 : :
2106 : 86641 : return str;
2107 : 33967 : }
2108 : :
2109 : : #ifdef G_OS_WIN32
2110 : :
2111 : : static gchar *
2112 : 208302 : g_build_pathname_va (const gchar *first_element,
2113 : : va_list *args,
2114 : : gchar **str_array)
2115 : : {
2116 : : /* Code copied from g_build_pathv(), and modified to use two
2117 : : * alternative single-character separators.
2118 : : */
2119 : : GString *result;
2120 : 208302 : gboolean is_first = TRUE;
2121 : 208302 : gboolean have_leading = FALSE;
2122 : 208302 : const gchar *single_element = NULL;
2123 : : const gchar *next_element;
2124 : 208302 : const gchar *last_trailing = NULL;
2125 : 208302 : gchar current_separator = '\\';
2126 : 208302 : size_t i = 0;
2127 : :
2128 : 208302 : result = g_string_new (NULL);
2129 : :
2130 : 208302 : if (str_array)
2131 : 509 : next_element = str_array[i++];
2132 : : else
2133 : 207793 : next_element = first_element;
2134 : :
2135 : 626564 : while (TRUE)
2136 : : {
2137 : : const gchar *element;
2138 : : const gchar *start;
2139 : : const gchar *end;
2140 : :
2141 : 627094 : if (next_element)
2142 : : {
2143 : 418792 : element = next_element;
2144 : 418792 : if (str_array)
2145 : 1281 : next_element = str_array[i++];
2146 : : else
2147 : 417511 : next_element = va_arg (*args, gchar *);
2148 : 418792 : }
2149 : : else
2150 : 208302 : break;
2151 : :
2152 : : /* Ignore empty elements */
2153 : 418792 : if (!*element)
2154 : 473 : continue;
2155 : :
2156 : 418319 : start = element;
2157 : :
2158 : : if (TRUE)
2159 : : {
2160 : 837066 : while (start &&
2161 : 418747 : (*start == '\\' || *start == '/'))
2162 : : {
2163 : 428 : current_separator = *start;
2164 : 428 : start++;
2165 : : }
2166 : : }
2167 : :
2168 : 418319 : end = start + strlen (start);
2169 : :
2170 : : if (TRUE)
2171 : : {
2172 : 836736 : while (end >= start + 1 &&
2173 : 418360 : (end[-1] == '\\' || end[-1] == '/'))
2174 : : {
2175 : 98 : current_separator = end[-1];
2176 : 98 : end--;
2177 : : }
2178 : :
2179 : 418319 : last_trailing = end;
2180 : 836715 : while (last_trailing >= element + 1 &&
2181 : 418339 : (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
2182 : 77 : last_trailing--;
2183 : :
2184 : 418319 : if (!have_leading)
2185 : : {
2186 : : /* If the leading and trailing separator strings are in the
2187 : : * same element and overlap, the result is exactly that element
2188 : : */
2189 : 208300 : if (last_trailing <= start)
2190 : 33 : single_element = element;
2191 : :
2192 : 208300 : g_string_append_len (result, element, start - element);
2193 : 208300 : have_leading = TRUE;
2194 : 208300 : }
2195 : : else
2196 : 210019 : single_element = NULL;
2197 : : }
2198 : :
2199 : 418319 : if (end == start)
2200 : 57 : continue;
2201 : :
2202 : 418262 : if (!is_first)
2203 : 209966 : g_string_append_len (result, ¤t_separator, 1);
2204 : :
2205 : 418262 : g_string_append_len (result, start, end - start);
2206 : 418262 : is_first = FALSE;
2207 : : }
2208 : :
2209 : 208302 : if (single_element)
2210 : : {
2211 : 4 : g_string_free (result, TRUE);
2212 : 4 : return g_strdup (single_element);
2213 : : }
2214 : : else
2215 : : {
2216 : 208298 : if (last_trailing)
2217 : 208296 : g_string_append (result, last_trailing);
2218 : :
2219 : 208298 : return g_string_free (result, FALSE);
2220 : : }
2221 : 208302 : }
2222 : :
2223 : : #endif
2224 : :
2225 : : static gchar *
2226 : 230850 : g_build_filename_va (const gchar *first_argument,
2227 : : va_list *args,
2228 : : gchar **str_array)
2229 : : {
2230 : : gchar *str;
2231 : :
2232 : : #ifndef G_OS_WIN32
2233 : 22548 : str = g_build_path_va (G_DIR_SEPARATOR_S, first_argument, args, str_array);
2234 : : #else
2235 : 208302 : str = g_build_pathname_va (first_argument, args, str_array);
2236 : : #endif
2237 : :
2238 : 230850 : return str;
2239 : : }
2240 : :
2241 : : /**
2242 : : * g_build_filename_valist:
2243 : : * @first_element: (type filename): the first element in the path
2244 : : * @args: va_list of remaining elements in path
2245 : : *
2246 : : * Creates a filename from a list of elements using the correct
2247 : : * separator for the current platform.
2248 : : *
2249 : : * Behaves exactly like g_build_filename(), but takes the path elements
2250 : : * as a va_list.
2251 : : *
2252 : : * This function is mainly meant for implementing other variadic arguments
2253 : : * functions.
2254 : : *
2255 : : * Returns: (type filename) (transfer full): the newly allocated path
2256 : : *
2257 : : * Since: 2.56
2258 : : */
2259 : : gchar *
2260 : 70 : g_build_filename_valist (const gchar *first_element,
2261 : : va_list *args)
2262 : : {
2263 : 70 : g_return_val_if_fail (first_element != NULL, NULL);
2264 : :
2265 : 70 : return g_build_filename_va (first_element, args, NULL);
2266 : 27 : }
2267 : :
2268 : : /**
2269 : : * g_build_filenamev:
2270 : : * @args: (array zero-terminated=1) (element-type filename): %NULL-terminated
2271 : : * array of strings containing the path elements.
2272 : : *
2273 : : * Creates a filename from a vector of elements using the correct
2274 : : * separator for the current platform.
2275 : : *
2276 : : * This function behaves exactly like g_build_filename(), but takes the path
2277 : : * elements as a string array, instead of varargs. This function is mainly
2278 : : * meant for language bindings.
2279 : : *
2280 : : * If you are building a path programmatically you may want to use
2281 : : * #GPathBuf instead.
2282 : : *
2283 : : * Returns: (type filename) (transfer full): the newly allocated path
2284 : : *
2285 : : * Since: 2.8
2286 : : */
2287 : : gchar *
2288 : 1372 : g_build_filenamev (gchar **args)
2289 : : {
2290 : 1372 : return g_build_filename_va (NULL, NULL, args);
2291 : : }
2292 : :
2293 : : /**
2294 : : * g_build_filename:
2295 : : * @first_element: (type filename): the first element in the path
2296 : : * @...: remaining elements in path, terminated by %NULL
2297 : : *
2298 : : * Creates a filename from a series of elements using the correct
2299 : : * separator for the current platform.
2300 : : *
2301 : : * On Unix, this function behaves identically to `g_build_path
2302 : : * (G_DIR_SEPARATOR_S, first_element, ....)`.
2303 : : *
2304 : : * On Windows, it takes into account that either the backslash
2305 : : * (`\` or slash (`/`) can be used as separator in filenames, but
2306 : : * otherwise behaves as on UNIX. When file pathname separators need
2307 : : * to be inserted, the one that last previously occurred in the
2308 : : * parameters (reading from left to right) is used.
2309 : : *
2310 : : * No attempt is made to force the resulting filename to be an absolute
2311 : : * path. If the first element is a relative path, the result will
2312 : : * be a relative path.
2313 : : *
2314 : : * If you are building a path programmatically you may want to use
2315 : : * #GPathBuf instead.
2316 : : *
2317 : : * Returns: (type filename) (transfer full): the newly allocated path
2318 : : */
2319 : : gchar *
2320 : 229408 : g_build_filename (const gchar *first_element,
2321 : : ...)
2322 : : {
2323 : : gchar *str;
2324 : : va_list args;
2325 : :
2326 : 229408 : va_start (args, first_element);
2327 : 229408 : str = g_build_filename_va (first_element, &args, NULL);
2328 : 229408 : va_end (args);
2329 : :
2330 : 229408 : return str;
2331 : : }
2332 : :
2333 : : /**
2334 : : * g_file_read_link:
2335 : : * @filename: (type filename): the symbolic link
2336 : : * @error: return location for a #GError
2337 : : *
2338 : : * Reads the contents of the symbolic link @filename like the POSIX
2339 : : * `readlink()` function.
2340 : : *
2341 : : * The returned string is in the encoding used for filenames. Use
2342 : : * g_filename_to_utf8() to convert it to UTF-8.
2343 : : *
2344 : : * The returned string may also be a relative path. Use g_build_filename()
2345 : : * to convert it to an absolute path:
2346 : : *
2347 : : * |[<!-- language="C" -->
2348 : : * g_autoptr(GError) local_error = NULL;
2349 : : * g_autofree gchar *link_target = g_file_read_link ("/etc/localtime", &local_error);
2350 : : *
2351 : : * if (local_error != NULL)
2352 : : * g_error ("Error reading link: %s", local_error->message);
2353 : : *
2354 : : * if (!g_path_is_absolute (link_target))
2355 : : * {
2356 : : * g_autofree gchar *absolute_link_target = g_build_filename ("/etc", link_target, NULL);
2357 : : * g_free (link_target);
2358 : : * link_target = g_steal_pointer (&absolute_link_target);
2359 : : * }
2360 : : * ]|
2361 : : *
2362 : : * Returns: (type filename) (transfer full): A newly-allocated string with
2363 : : * the contents of the symbolic link, or %NULL if an error occurred.
2364 : : *
2365 : : * Since: 2.4
2366 : : */
2367 : : gchar *
2368 : 10363 : g_file_read_link (const gchar *filename,
2369 : : GError **error)
2370 : : {
2371 : : #if defined (HAVE_READLINK)
2372 : : gchar *buffer;
2373 : : size_t size;
2374 : : gssize read_size;
2375 : :
2376 : 10362 : g_return_val_if_fail (filename != NULL, NULL);
2377 : 10361 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2378 : :
2379 : 10361 : size = 256;
2380 : 10361 : buffer = g_malloc (size);
2381 : :
2382 : : while (TRUE)
2383 : : {
2384 : 10361 : read_size = readlink (filename, buffer, size);
2385 : 10361 : if (read_size < 0)
2386 : : {
2387 : 5 : int saved_errno = errno;
2388 : 5 : if (error)
2389 : 5 : set_file_error (error,
2390 : : filename,
2391 : : _("Failed to read the symbolic link “%s”: %s"),
2392 : : saved_errno);
2393 : 5 : g_free (buffer);
2394 : 5 : return NULL;
2395 : : }
2396 : :
2397 : 10356 : if ((size_t) read_size < size)
2398 : : {
2399 : 10356 : buffer[read_size] = 0;
2400 : 10356 : return buffer;
2401 : : }
2402 : :
2403 : 0 : size *= 2;
2404 : 0 : buffer = g_realloc (buffer, size);
2405 : : }
2406 : : #elif defined (G_OS_WIN32)
2407 : : gchar *buffer;
2408 : : gssize read_size;
2409 : :
2410 : 1 : g_return_val_if_fail (filename != NULL, NULL);
2411 : 1 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2412 : :
2413 : 1 : read_size = g_win32_readlink_utf8 (filename, NULL, 0, &buffer, TRUE);
2414 : 1 : if (read_size < 0)
2415 : : {
2416 : 1 : int saved_errno = errno;
2417 : 1 : if (error)
2418 : 2 : set_file_error (error,
2419 : 1 : filename,
2420 : 1 : _("Failed to read the symbolic link “%s”: %s"),
2421 : 1 : saved_errno);
2422 : 1 : return NULL;
2423 : : }
2424 : 0 : else if (read_size == 0)
2425 : 0 : return strdup ("");
2426 : : else
2427 : 0 : return buffer;
2428 : : #else
2429 : : g_return_val_if_fail (filename != NULL, NULL);
2430 : : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
2431 : :
2432 : : g_set_error_literal (error,
2433 : : G_FILE_ERROR,
2434 : : G_FILE_ERROR_INVAL,
2435 : : _("Symbolic links not supported"));
2436 : :
2437 : : return NULL;
2438 : : #endif
2439 : 1 : }
2440 : :
2441 : : /**
2442 : : * g_path_is_absolute:
2443 : : * @file_name: (type filename): a file name
2444 : : *
2445 : : * Returns %TRUE if the given @file_name is an absolute file name.
2446 : : * Note that this is a somewhat vague concept on Windows.
2447 : : *
2448 : : * On POSIX systems, an absolute file name is well-defined. It always
2449 : : * starts from the single root directory. For example "/usr/local".
2450 : : *
2451 : : * On Windows, the concepts of current drive and drive-specific
2452 : : * current directory introduce vagueness. This function interprets as
2453 : : * an absolute file name one that either begins with a directory
2454 : : * separator such as "\Users\tml" or begins with the root on a drive,
2455 : : * for example "C:\Windows". The first case also includes UNC paths
2456 : : * such as "\\\\myserver\docs\foo". In all cases, either slashes or
2457 : : * backslashes are accepted.
2458 : : *
2459 : : * Note that a file name relative to the current drive root does not
2460 : : * truly specify a file uniquely over time and across processes, as
2461 : : * the current drive is a per-process value and can be changed.
2462 : : *
2463 : : * File names relative the current directory on some specific drive,
2464 : : * such as "D:foo/bar", are not interpreted as absolute by this
2465 : : * function, but they obviously are not relative to the normal current
2466 : : * directory as returned by getcwd() or g_get_current_dir()
2467 : : * either. Such paths should be avoided, or need to be handled using
2468 : : * Windows-specific code.
2469 : : *
2470 : : * Returns: %TRUE if @file_name is absolute
2471 : : */
2472 : : gboolean
2473 : 94170 : g_path_is_absolute (const gchar *file_name)
2474 : : {
2475 : 94170 : g_return_val_if_fail (file_name != NULL, FALSE);
2476 : :
2477 : 94166 : if (G_IS_DIR_SEPARATOR (file_name[0]))
2478 : 87387 : return TRUE;
2479 : :
2480 : : #ifdef G_OS_WIN32
2481 : : /* Recognize drive letter on native Windows */
2482 : 2748 : if (g_ascii_isalpha (file_name[0]) &&
2483 : 2706 : file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
2484 : 1880 : return TRUE;
2485 : : #endif
2486 : :
2487 : 4899 : return FALSE;
2488 : 32927 : }
2489 : :
2490 : : /**
2491 : : * g_path_skip_root:
2492 : : * @file_name: (type filename): a file name
2493 : : *
2494 : : * Returns a pointer into @file_name after the root component,
2495 : : * i.e. after the "/" in UNIX or "C:\" under Windows. If @file_name
2496 : : * is not an absolute path it returns %NULL.
2497 : : *
2498 : : * Returns: (type filename) (nullable): a pointer into @file_name after the
2499 : : * root component
2500 : : */
2501 : : const gchar *
2502 : 15749 : g_path_skip_root (const gchar *file_name)
2503 : : {
2504 : 15749 : g_return_val_if_fail (file_name != NULL, NULL);
2505 : :
2506 : : #ifdef G_PLATFORM_WIN32
2507 : : /* Skip \\server\share or //server/share */
2508 : 1627 : if (G_IS_DIR_SEPARATOR (file_name[0]) &&
2509 : 484 : G_IS_DIR_SEPARATOR (file_name[1]) &&
2510 : 509 : file_name[2] &&
2511 : 28 : !G_IS_DIR_SEPARATOR (file_name[2]))
2512 : : {
2513 : : gchar *p;
2514 : 20 : p = strchr (file_name + 2, G_DIR_SEPARATOR);
2515 : :
2516 : : #ifdef G_OS_WIN32
2517 : : {
2518 : : gchar *q;
2519 : :
2520 : 20 : q = strchr (file_name + 2, '/');
2521 : 20 : if (p == NULL || (q != NULL && q < p))
2522 : 10 : p = q;
2523 : : }
2524 : : #endif
2525 : :
2526 : 20 : if (p && p > file_name + 2 && p[1])
2527 : : {
2528 : 16 : file_name = p + 1;
2529 : :
2530 : 76 : while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
2531 : 60 : file_name++;
2532 : :
2533 : : /* Possibly skip a backslash after the share name */
2534 : 16 : if (G_IS_DIR_SEPARATOR (file_name[0]))
2535 : 7 : file_name++;
2536 : :
2537 : 16 : return (gchar *)file_name;
2538 : : }
2539 : 4 : }
2540 : : #endif
2541 : :
2542 : : /* Skip initial slashes */
2543 : 15549 : if (G_IS_DIR_SEPARATOR (file_name[0]))
2544 : : {
2545 : 28810 : while (G_IS_DIR_SEPARATOR (file_name[0]))
2546 : 14436 : file_name++;
2547 : 14374 : return (gchar *)file_name;
2548 : : }
2549 : :
2550 : : #ifdef G_OS_WIN32
2551 : : /* Skip X:\ */
2552 : 1171 : if (g_ascii_isalpha (file_name[0]) &&
2553 : 1194 : file_name[1] == ':' &&
2554 : 1166 : G_IS_DIR_SEPARATOR (file_name[2]))
2555 : 1166 : return (gchar *)file_name + 3;
2556 : : #endif
2557 : :
2558 : 9 : return NULL;
2559 : 1443 : }
2560 : :
2561 : : /**
2562 : : * g_basename:
2563 : : * @file_name: (type filename): the name of the file
2564 : : *
2565 : : * Gets the name of the file without any leading directory
2566 : : * components. It returns a pointer into the given file name
2567 : : * string.
2568 : : *
2569 : : * Returns: (type filename): the name of the file without any leading
2570 : : * directory components
2571 : : *
2572 : : * Deprecated:2.2: Use g_path_get_basename() instead, but notice
2573 : : * that g_path_get_basename() allocates new memory for the
2574 : : * returned string, unlike this function which returns a pointer
2575 : : * into the argument.
2576 : : */
2577 : : const gchar *
2578 : 4 : g_basename (const gchar *file_name)
2579 : : {
2580 : : const gchar *base;
2581 : :
2582 : 4 : g_return_val_if_fail (file_name != NULL, NULL);
2583 : :
2584 : 2 : base = strrchr (file_name, G_DIR_SEPARATOR);
2585 : :
2586 : : #ifdef G_OS_WIN32
2587 : : {
2588 : : const gchar *q;
2589 : 1 : q = strrchr (file_name, '/');
2590 : 1 : if (base == NULL || (q != NULL && q > base))
2591 : 1 : base = q;
2592 : : }
2593 : : #endif
2594 : :
2595 : 2 : if (base)
2596 : 2 : return base + 1;
2597 : :
2598 : : #ifdef G_OS_WIN32
2599 : 0 : if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
2600 : 0 : return (gchar*) file_name + 2;
2601 : : #endif
2602 : :
2603 : 0 : return (gchar*) file_name;
2604 : 2 : }
2605 : :
2606 : : /**
2607 : : * g_path_get_basename:
2608 : : * @file_name: (type filename): the name of the file
2609 : : *
2610 : : * Gets the last component of the filename.
2611 : : *
2612 : : * If @file_name ends with a directory separator it gets the component
2613 : : * before the last slash. If @file_name consists only of directory
2614 : : * separators (and on Windows, possibly a drive letter), a single
2615 : : * separator is returned. If @file_name is empty, it gets ".".
2616 : : *
2617 : : * Returns: (type filename) (transfer full): a newly allocated string
2618 : : * containing the last component of the filename
2619 : : */
2620 : : gchar *
2621 : 2057 : g_path_get_basename (const gchar *file_name)
2622 : : {
2623 : : size_t base;
2624 : : size_t last_nonslash;
2625 : : gsize len;
2626 : : gchar *retval;
2627 : :
2628 : 2057 : g_return_val_if_fail (file_name != NULL, NULL);
2629 : :
2630 : 2055 : if (file_name[0] == '\0')
2631 : 4 : return g_strdup (".");
2632 : :
2633 : 2051 : last_nonslash = strlen (file_name) - 1;
2634 : :
2635 : 2536 : while (last_nonslash > 0 && G_IS_DIR_SEPARATOR (file_name[last_nonslash]))
2636 : 55 : last_nonslash--;
2637 : :
2638 : 2051 : if (last_nonslash == 0 && G_IS_DIR_SEPARATOR (file_name[0]))
2639 : : /* string only containing slashes */
2640 : 13 : return g_strdup (G_DIR_SEPARATOR_S);
2641 : :
2642 : : #ifdef G_OS_WIN32
2643 : 425 : if (last_nonslash == 1 &&
2644 : 5 : g_ascii_isalpha (file_name[0]) &&
2645 : 0 : file_name[1] == ':')
2646 : : /* string only containing slashes and a drive */
2647 : 0 : return g_strdup (G_DIR_SEPARATOR_S);
2648 : : #endif
2649 : 2038 : base = last_nonslash;
2650 : :
2651 : 30134 : while (base > 0 && !G_IS_DIR_SEPARATOR (file_name[base]))
2652 : 28096 : base--;
2653 : :
2654 : : /* Does the file_name start without a directory separator, with the only
2655 : : * directory separators being at the end of the string? e.g. `dir/` */
2656 : 2038 : if (base == 0 && !G_IS_DIR_SEPARATOR (file_name[0]))
2657 : : {
2658 : 126 : base = 0;
2659 : :
2660 : : #ifdef G_OS_WIN32
2661 : : /* Does it start with a drive letter? e.g. `C:dir/`
2662 : : * If so, skip that. */
2663 : 30 : if (g_ascii_isalpha (file_name[0]) &&
2664 : 22 : file_name[1] == ':')
2665 : 0 : base = 2;
2666 : : #endif /* G_OS_WIN32 */
2667 : 30 : }
2668 : : else
2669 : : {
2670 : : /* Otherwise, `base` now points at the last directory separator character
2671 : : * before the component we want as the basename, so increase the index
2672 : : * again. */
2673 : 1912 : base += 1;
2674 : : }
2675 : :
2676 : 2038 : len = last_nonslash - base + 1;
2677 : 2038 : g_assert (len < SIZE_MAX);
2678 : 2038 : retval = g_malloc (len + 1);
2679 : 2038 : memcpy (retval, file_name + base, len);
2680 : 2038 : retval[len] = '\0';
2681 : :
2682 : 2038 : return retval;
2683 : 433 : }
2684 : :
2685 : : /**
2686 : : * g_dirname:
2687 : : * @file_name: (type filename): the name of the file
2688 : : *
2689 : : * Gets the directory components of a file name.
2690 : : *
2691 : : * If the file name has no directory components "." is returned.
2692 : : * The returned string should be freed when no longer needed.
2693 : : *
2694 : : * Returns: (type filename) (transfer full): the directory components of the file
2695 : : *
2696 : : * Deprecated: use g_path_get_dirname() instead
2697 : : */
2698 : :
2699 : : /**
2700 : : * g_path_get_dirname:
2701 : : * @file_name: (type filename): the name of the file
2702 : : *
2703 : : * Gets the directory components of a file name. For example, the directory
2704 : : * component of `/usr/bin/test` is `/usr/bin`. The directory component of `/`
2705 : : * is `/`.
2706 : : *
2707 : : * If the file name has no directory components "." is returned.
2708 : : * The returned string should be freed when no longer needed.
2709 : : *
2710 : : * Returns: (type filename) (transfer full): the directory components of the file
2711 : : */
2712 : : gchar *
2713 : 15638 : g_path_get_dirname (const gchar *file_name)
2714 : : {
2715 : : const gchar *base;
2716 : : gchar *base_p;
2717 : : gsize len;
2718 : :
2719 : 15638 : g_return_val_if_fail (file_name != NULL, NULL);
2720 : :
2721 : 15636 : base = strrchr (file_name, G_DIR_SEPARATOR);
2722 : :
2723 : : #ifdef G_OS_WIN32
2724 : : {
2725 : : const gchar *q;
2726 : 1493 : q = strrchr (file_name, '/');
2727 : 1493 : if (base == NULL || (q != NULL && q > base))
2728 : 608 : base = q;
2729 : : }
2730 : : #endif
2731 : :
2732 : 15676 : if (!base)
2733 : : {
2734 : : #ifdef G_OS_WIN32
2735 : 19 : if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
2736 : : {
2737 : : gchar drive_colon_dot[4];
2738 : :
2739 : 2 : drive_colon_dot[0] = file_name[0];
2740 : 2 : drive_colon_dot[1] = ':';
2741 : 2 : drive_colon_dot[2] = '.';
2742 : 2 : drive_colon_dot[3] = '\0';
2743 : :
2744 : 2 : return g_strdup (drive_colon_dot);
2745 : : }
2746 : : #endif
2747 : 37 : return g_strdup (".");
2748 : : }
2749 : :
2750 : 32783 : while (base > file_name && G_IS_DIR_SEPARATOR (*base))
2751 : 15632 : base--;
2752 : :
2753 : : #ifdef G_OS_WIN32
2754 : : /* base points to the char before the last slash.
2755 : : *
2756 : : * In case file_name is the root of a drive (X:\) or a child of the
2757 : : * root of a drive (X:\foo), include the slash.
2758 : : *
2759 : : * In case file_name is the root share of an UNC path
2760 : : * (\\server\share), add a slash, returning \\server\share\ .
2761 : : *
2762 : : * In case file_name is a direct child of a share in an UNC path
2763 : : * (\\server\share\foo), include the slash after the share name,
2764 : : * returning \\server\share\ .
2765 : : */
2766 : 1514 : if (base == file_name + 1 &&
2767 : 19 : g_ascii_isalpha (file_name[0]) &&
2768 : 8 : file_name[1] == ':')
2769 : 8 : base++;
2770 : 1506 : else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
2771 : 61 : G_IS_DIR_SEPARATOR (file_name[1]) &&
2772 : 61 : file_name[2] &&
2773 : 3 : !G_IS_DIR_SEPARATOR (file_name[2]) &&
2774 : 0 : base >= file_name + 2)
2775 : : {
2776 : 0 : const gchar *p = file_name + 2;
2777 : 0 : while (*p && !G_IS_DIR_SEPARATOR (*p))
2778 : 0 : p++;
2779 : 0 : if (p == base + 1)
2780 : : {
2781 : 0 : len = (guint) strlen (file_name) + 1;
2782 : 0 : base_p = g_new (gchar, len + 1);
2783 : 0 : strcpy (base_p, file_name);
2784 : 0 : base_p[len-1] = G_DIR_SEPARATOR;
2785 : 0 : base_p[len] = 0;
2786 : 0 : return base_p;
2787 : : }
2788 : 0 : if (G_IS_DIR_SEPARATOR (*p))
2789 : : {
2790 : 0 : p++;
2791 : 0 : while (*p && !G_IS_DIR_SEPARATOR (*p))
2792 : 0 : p++;
2793 : 0 : if (p == base + 1)
2794 : 0 : base++;
2795 : 0 : }
2796 : 0 : }
2797 : : #endif
2798 : :
2799 : 15613 : len = (guint) 1 + base - file_name;
2800 : 15613 : base_p = g_new (gchar, len + 1);
2801 : 15613 : memmove (base_p, file_name, len);
2802 : 15613 : base_p[len] = 0;
2803 : :
2804 : 15613 : return base_p;
2805 : 1510 : }
2806 : :
2807 : : /**
2808 : : * g_canonicalize_filename:
2809 : : * @filename: (type filename): the name of the file
2810 : : * @relative_to: (type filename) (nullable): the relative directory, or %NULL
2811 : : * to use the current working directory
2812 : : *
2813 : : * Gets the canonical file name from @filename. All triple slashes are turned into
2814 : : * single slashes, and all `..` and `.`s resolved against @relative_to.
2815 : : *
2816 : : * Symlinks are not followed, and the returned path is guaranteed to be absolute.
2817 : : *
2818 : : * If @filename is an absolute path, @relative_to is ignored. Otherwise,
2819 : : * @relative_to will be prepended to @filename to make it absolute. @relative_to
2820 : : * must be an absolute path, or %NULL. If @relative_to is %NULL, it'll fallback
2821 : : * to g_get_current_dir().
2822 : : *
2823 : : * This function never fails, and will canonicalize file paths even if they don't
2824 : : * exist.
2825 : : *
2826 : : * No file system I/O is done.
2827 : : *
2828 : : * Returns: (type filename) (transfer full): a newly allocated string with the
2829 : : * canonical file path
2830 : : *
2831 : : * Since: 2.58
2832 : : */
2833 : : gchar *
2834 : 13364 : g_canonicalize_filename (const gchar *filename,
2835 : : const gchar *relative_to)
2836 : : {
2837 : : gchar *canon, *input, *output, *after_root, *output_start;
2838 : :
2839 : 13364 : g_return_val_if_fail (relative_to == NULL || g_path_is_absolute (relative_to), NULL);
2840 : :
2841 : 13364 : if (!g_path_is_absolute (filename))
2842 : : {
2843 : 116 : gchar *cwd_allocated = NULL;
2844 : : const gchar *cwd;
2845 : :
2846 : 116 : if (relative_to != NULL)
2847 : 59 : cwd = relative_to;
2848 : : else
2849 : 57 : cwd = cwd_allocated = g_get_current_dir ();
2850 : :
2851 : 116 : canon = g_build_filename (cwd, filename, NULL);
2852 : 116 : g_free (cwd_allocated);
2853 : 62 : }
2854 : : else
2855 : : {
2856 : 13248 : canon = g_strdup (filename);
2857 : : }
2858 : :
2859 : 13364 : after_root = (char *)g_path_skip_root (canon);
2860 : :
2861 : 13364 : if (after_root == NULL)
2862 : : {
2863 : : /* This shouldn't really happen, as g_get_current_dir() should
2864 : : return an absolute pathname, but bug 573843 shows this is
2865 : : not always happening */
2866 : 0 : g_free (canon);
2867 : 0 : return g_build_filename (G_DIR_SEPARATOR_S, filename, NULL);
2868 : : }
2869 : :
2870 : : /* Find the first dir separator and use the canonical dir separator. */
2871 : 14741 : for (output = after_root - 1;
2872 : 26778 : (output >= canon) && G_IS_DIR_SEPARATOR (*output);
2873 : 13414 : output--)
2874 : 13414 : *output = G_DIR_SEPARATOR;
2875 : :
2876 : : /* 1 to re-increment after the final decrement above (so that output >= canon),
2877 : : * and 1 to skip the first `/`. There might not be a first `/` if
2878 : : * the @canon is a Windows `//server/share` style path with no
2879 : : * trailing directories. @after_root will be '\0' in that case. */
2880 : 13364 : output++;
2881 : 13364 : if (*output == G_DIR_SEPARATOR)
2882 : 13356 : output++;
2883 : :
2884 : : /* POSIX allows double slashes at the start to mean something special
2885 : : * (as does windows too). So, "//" != "/", but more than two slashes
2886 : : * is treated as "/".
2887 : : */
2888 : 13364 : if (after_root - output == 1)
2889 : 30 : output++;
2890 : :
2891 : 13364 : input = after_root;
2892 : 13364 : output_start = output;
2893 : 65503 : while (*input)
2894 : : {
2895 : : /* input points to the next non-separator to be processed. */
2896 : : /* output points to the next location to write to. */
2897 : 65320 : g_assert (input > canon && G_IS_DIR_SEPARATOR (input[-1]));
2898 : 65320 : g_assert (output > canon && G_IS_DIR_SEPARATOR (output[-1]));
2899 : 65320 : g_assert (input >= output);
2900 : :
2901 : : /* Ignore repeated dir separators. */
2902 : 65396 : while (G_IS_DIR_SEPARATOR (input[0]))
2903 : 76 : input++;
2904 : :
2905 : : /* Ignore single dot directory components. */
2906 : 65320 : if (input[0] == '.' && (input[1] == 0 || G_IS_DIR_SEPARATOR (input[1])))
2907 : : {
2908 : 98 : if (input[1] == 0)
2909 : 23 : break;
2910 : 75 : input += 2;
2911 : 41 : }
2912 : : /* Remove double-dot directory components along with the preceding
2913 : : * path component. */
2914 : 65246 : else if (input[0] == '.' && input[1] == '.' &&
2915 : 87 : (input[2] == 0 || G_IS_DIR_SEPARATOR (input[2])))
2916 : : {
2917 : 83 : if (output > output_start)
2918 : : {
2919 : 42 : do
2920 : : {
2921 : 314 : output--;
2922 : 243 : }
2923 : 314 : while (!G_IS_DIR_SEPARATOR (output[-1]) && output > output_start);
2924 : 42 : }
2925 : 83 : if (input[2] == 0)
2926 : 12 : break;
2927 : 71 : input += 3;
2928 : 46 : }
2929 : : /* Copy the input to the output until the next separator,
2930 : : * while converting it to canonical separator */
2931 : : else
2932 : : {
2933 : 453309 : while (*input && !G_IS_DIR_SEPARATOR (*input))
2934 : 388170 : *output++ = *input++;
2935 : 65139 : if (input[0] == 0)
2936 : 13146 : break;
2937 : 51993 : input++;
2938 : 51993 : *output++ = G_DIR_SEPARATOR;
2939 : : }
2940 : : }
2941 : :
2942 : : /* Remove a potentially trailing dir separator */
2943 : 13364 : if (output > output_start && G_IS_DIR_SEPARATOR (output[-1]))
2944 : 93 : output--;
2945 : :
2946 : 13364 : *output = '\0';
2947 : :
2948 : 13364 : return canon;
2949 : 447 : }
2950 : :
2951 : : #if defined(MAXPATHLEN)
2952 : : #define G_PATH_LENGTH MAXPATHLEN
2953 : : #elif defined(PATH_MAX)
2954 : : #define G_PATH_LENGTH PATH_MAX
2955 : : #elif defined(_PC_PATH_MAX)
2956 : : #define G_PATH_LENGTH sysconf(_PC_PATH_MAX)
2957 : : #else
2958 : : #define G_PATH_LENGTH 2048
2959 : : #endif
2960 : :
2961 : : /**
2962 : : * g_get_current_dir:
2963 : : *
2964 : : * Gets the current directory.
2965 : : *
2966 : : * The returned string should be freed when no longer needed.
2967 : : * The encoding of the returned string is system defined.
2968 : : * On Windows, it is always UTF-8.
2969 : : *
2970 : : * Since GLib 2.40, this function will return the value of the "PWD"
2971 : : * environment variable if it is set and it happens to be the same as
2972 : : * the current directory. This can make a difference in the case that
2973 : : * the current directory is the target of a symbolic link.
2974 : : *
2975 : : * Returns: (type filename) (transfer full): the current directory
2976 : : */
2977 : : gchar *
2978 : 1486 : g_get_current_dir (void)
2979 : : {
2980 : : #ifdef G_OS_WIN32
2981 : :
2982 : 662 : gchar *dir = NULL;
2983 : : wchar_t dummy[2], *wdir;
2984 : : DWORD len;
2985 : :
2986 : 662 : len = GetCurrentDirectoryW (2, dummy);
2987 : 662 : wdir = g_new (wchar_t, len);
2988 : :
2989 : 662 : if (GetCurrentDirectoryW (len, wdir) == len - 1)
2990 : 662 : dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
2991 : :
2992 : 662 : g_free (wdir);
2993 : :
2994 : 662 : if (dir == NULL)
2995 : 0 : dir = g_strdup ("\\");
2996 : :
2997 : 662 : return dir;
2998 : :
2999 : : #else
3000 : : const gchar *pwd;
3001 : 824 : gchar *buffer = NULL;
3002 : 824 : gchar *dir = NULL;
3003 : : static gsize buffer_size = 0;
3004 : : struct stat pwdbuf, dotbuf;
3005 : :
3006 : 824 : pwd = g_getenv ("PWD");
3007 : 1648 : if (pwd != NULL &&
3008 : 1648 : g_stat (".", &dotbuf) == 0 && g_stat (pwd, &pwdbuf) == 0 &&
3009 : 824 : dotbuf.st_dev == pwdbuf.st_dev && dotbuf.st_ino == pwdbuf.st_ino)
3010 : 21 : return g_strdup (pwd);
3011 : :
3012 : 803 : if (buffer_size == 0)
3013 : 690 : buffer_size = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
3014 : :
3015 : 803 : while (buffer_size < G_MAXSIZE / 2)
3016 : : {
3017 : 803 : g_free (buffer);
3018 : 803 : buffer = g_new (gchar, buffer_size);
3019 : 803 : *buffer = 0;
3020 : 803 : dir = getcwd (buffer, buffer_size);
3021 : :
3022 : 803 : if (dir || errno != ERANGE)
3023 : : break;
3024 : :
3025 : 0 : buffer_size *= 2;
3026 : : }
3027 : :
3028 : : /* Check that getcwd() nul-terminated the string. It should do, but the specs
3029 : : * don’t actually explicitly state that:
3030 : : * https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html */
3031 : 803 : g_assert (dir == NULL || strnlen (dir, buffer_size) < buffer_size);
3032 : :
3033 : 803 : if (!dir || !*buffer)
3034 : : {
3035 : : /* Fallback return value */
3036 : 0 : g_assert (buffer_size >= 2);
3037 : 0 : g_assert (buffer != NULL);
3038 : 0 : buffer[0] = G_DIR_SEPARATOR;
3039 : 0 : buffer[1] = 0;
3040 : : }
3041 : :
3042 : 803 : dir = g_strdup (buffer);
3043 : 803 : g_free (buffer);
3044 : :
3045 : 803 : return dir;
3046 : :
3047 : : #endif /* !G_OS_WIN32 */
3048 : : }
3049 : :
3050 : : #ifdef G_OS_WIN32
3051 : :
3052 : : /* Binary compatibility versions. Not for newly compiled code. */
3053 : :
3054 : : _GLIB_EXTERN gboolean g_file_test_utf8 (const gchar *filename,
3055 : : GFileTest test);
3056 : : _GLIB_EXTERN gboolean g_file_get_contents_utf8 (const gchar *filename,
3057 : : gchar **contents,
3058 : : gsize *length,
3059 : : GError **error);
3060 : : _GLIB_EXTERN gint g_mkstemp_utf8 (gchar *tmpl);
3061 : : _GLIB_EXTERN gint g_file_open_tmp_utf8 (const gchar *tmpl,
3062 : : gchar **name_used,
3063 : : GError **error);
3064 : : _GLIB_EXTERN gchar *g_get_current_dir_utf8 (void);
3065 : :
3066 : :
3067 : : gboolean
3068 : 0 : g_file_test_utf8 (const gchar *filename,
3069 : : GFileTest test)
3070 : : {
3071 : 0 : return g_file_test (filename, test);
3072 : : }
3073 : :
3074 : : gboolean
3075 : 0 : g_file_get_contents_utf8 (const gchar *filename,
3076 : : gchar **contents,
3077 : : gsize *length,
3078 : : GError **error)
3079 : : {
3080 : 0 : return g_file_get_contents (filename, contents, length, error);
3081 : : }
3082 : :
3083 : : gint
3084 : 0 : g_mkstemp_utf8 (gchar *tmpl)
3085 : : {
3086 : 0 : return g_mkstemp (tmpl);
3087 : : }
3088 : :
3089 : : gint
3090 : 0 : g_file_open_tmp_utf8 (const gchar *tmpl,
3091 : : gchar **name_used,
3092 : : GError **error)
3093 : : {
3094 : 0 : return g_file_open_tmp (tmpl, name_used, error);
3095 : : }
3096 : :
3097 : : gchar *
3098 : 0 : g_get_current_dir_utf8 (void)
3099 : : {
3100 : 0 : return g_get_current_dir ();
3101 : : }
3102 : :
3103 : : #endif
|