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