Imported Upstream version 2.74.3
[platform/upstream/glib.git] / glib / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
29  */
30
31 #include "config.h"
32
33 #include "gutils.h"
34 #include "gutilsprivate.h"
35
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <locale.h>
40 #include <string.h>
41 #include <ctype.h>              /* For tolower() */
42 #include <errno.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #ifdef G_OS_UNIX
46 #include <pwd.h>
47 #include <sys/utsname.h>
48 #include <unistd.h>
49 #endif
50 #include <sys/types.h>
51 #ifdef HAVE_SYS_PARAM_H
52 #include <sys/param.h>
53 #endif
54 #ifdef HAVE_CRT_EXTERNS_H 
55 #include <crt_externs.h> /* for _NSGetEnviron */
56 #endif
57 #ifdef HAVE_SYS_AUXV_H
58 #include <sys/auxv.h>
59 #endif
60
61 #include "glib-init.h"
62 #include "glib-private.h"
63 #include "genviron.h"
64 #include "gfileutils.h"
65 #include "ggettext.h"
66 #include "ghash.h"
67 #include "gthread.h"
68 #include "gtestutils.h"
69 #include "gunicode.h"
70 #include "gstrfuncs.h"
71 #include "garray.h"
72 #include "glibintl.h"
73 #include "gstdio.h"
74 #include "gquark.h"
75
76 #ifdef G_PLATFORM_WIN32
77 #include "gconvert.h"
78 #include "gwin32.h"
79 #endif
80
81
82 /**
83  * SECTION:misc_utils
84  * @title: Miscellaneous Utility Functions
85  * @short_description: a selection of portable utility functions
86  *
87  * These are portable utility functions.
88  */
89
90 #ifdef G_PLATFORM_WIN32
91 #  include <windows.h>
92 #  ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
93 #    define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
94 #    define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
95 #  endif
96 #  include <lmcons.h>           /* For UNLEN */
97 #endif /* G_PLATFORM_WIN32 */
98
99 #ifdef G_OS_WIN32
100 #  include <direct.h>
101 #  include <shlobj.h>
102 #  include <process.h>
103 #endif
104
105 #ifdef HAVE_CODESET
106 #include <langinfo.h>
107 #endif
108
109 /**
110  * g_memmove: 
111  * @dest: the destination address to copy the bytes to.
112  * @src: the source address to copy the bytes from.
113  * @len: the number of bytes to copy.
114  *
115  * Copies a block of memory @len bytes long, from @src to @dest.
116  * The source and destination areas may overlap.
117  *
118  * Deprecated:2.40: Just use memmove().
119  */
120
121 #ifdef G_OS_WIN32
122 #undef g_atexit
123 #endif
124
125 /**
126  * g_atexit:
127  * @func: (scope async): the function to call on normal program termination.
128  * 
129  * Specifies a function to be called at normal program termination.
130  *
131  * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor
132  * macro that maps to a call to the atexit() function in the C
133  * library. This means that in case the code that calls g_atexit(),
134  * i.e. atexit(), is in a DLL, the function will be called when the
135  * DLL is detached from the program. This typically makes more sense
136  * than that the function is called when the GLib DLL is detached,
137  * which happened earlier when g_atexit() was a function in the GLib
138  * DLL.
139  *
140  * The behaviour of atexit() in the context of dynamically loaded
141  * modules is not formally specified and varies wildly.
142  *
143  * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically
144  * loaded module which is unloaded before the program terminates might
145  * well cause a crash at program exit.
146  *
147  * Some POSIX systems implement atexit() like Windows, and have each
148  * dynamically loaded module maintain an own atexit chain that is
149  * called when the module is unloaded.
150  *
151  * On other POSIX systems, before a dynamically loaded module is
152  * unloaded, the registered atexit functions (if any) residing in that
153  * module are called, regardless where the code that registered them
154  * resided. This is presumably the most robust approach.
155  *
156  * As can be seen from the above, for portability it's best to avoid
157  * calling g_atexit() (or atexit()) except in the main executable of a
158  * program.
159  *
160  * Deprecated:2.32: It is best to avoid g_atexit().
161  */
162 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
163 void
164 g_atexit (GVoidFunc func)
165 {
166   gint result;
167   int errsv;
168
169   result = atexit ((void (*)(void)) func);
170   errsv = errno;
171   if (result)
172     {
173       g_error ("Could not register atexit() function: %s",
174                g_strerror (errsv));
175     }
176 }
177 G_GNUC_END_IGNORE_DEPRECATIONS
178
179 /* Based on execvp() from GNU Libc.
180  * Some of this code is cut-and-pasted into gspawn.c
181  */
182
183 static gchar*
184 my_strchrnul (const gchar *str, 
185               gchar        c)
186 {
187   gchar *p = (gchar*)str;
188   while (*p && (*p != c))
189     ++p;
190
191   return p;
192 }
193
194 #ifdef G_OS_WIN32
195
196 static gchar *inner_find_program_in_path (const gchar *program);
197
198 gchar*
199 g_find_program_in_path (const gchar *program)
200 {
201   const gchar *last_dot = strrchr (program, '.');
202
203   if (last_dot == NULL ||
204       strchr (last_dot, '\\') != NULL ||
205       strchr (last_dot, '/') != NULL)
206     {
207       const gint program_length = strlen (program);
208       gchar *pathext = g_build_path (";",
209                                      ".exe;.cmd;.bat;.com",
210                                      g_getenv ("PATHEXT"),
211                                      NULL);
212       gchar *p;
213       gchar *decorated_program;
214       gchar *retval;
215
216       p = pathext;
217       do
218         {
219           gchar *q = my_strchrnul (p, ';');
220
221           decorated_program = g_malloc (program_length + (q-p) + 1);
222           memcpy (decorated_program, program, program_length);
223           memcpy (decorated_program+program_length, p, q-p);
224           decorated_program [program_length + (q-p)] = '\0';
225           
226           retval = inner_find_program_in_path (decorated_program);
227           g_free (decorated_program);
228
229           if (retval != NULL)
230             {
231               g_free (pathext);
232               return retval;
233             }
234           p = q;
235         } while (*p++ != '\0');
236       g_free (pathext);
237       return NULL;
238     }
239   else
240     return inner_find_program_in_path (program);
241 }
242
243 #endif
244
245 /**
246  * g_find_program_in_path:
247  * @program: (type filename): a program name in the GLib file name encoding
248  * 
249  * Locates the first executable named @program in the user's path, in the
250  * same way that execvp() would locate it. Returns an allocated string
251  * with the absolute path name, or %NULL if the program is not found in
252  * the path. If @program is already an absolute path, returns a copy of
253  * @program if @program exists and is executable, and %NULL otherwise.
254  *  
255  * On Windows, if @program does not have a file type suffix, tries
256  * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
257  * the `PATHEXT` environment variable. 
258  * 
259  * On Windows, it looks for the file in the same way as CreateProcess() 
260  * would. This means first in the directory where the executing
261  * program was loaded from, then in the current directory, then in the
262  * Windows 32-bit system directory, then in the Windows directory, and
263  * finally in the directories in the `PATH` environment variable. If
264  * the program is found, the return value contains the full name
265  * including the type suffix.
266  *
267  * Returns: (type filename) (transfer full) (nullable): a newly-allocated
268  *   string with the absolute path, or %NULL
269  **/
270 #ifdef G_OS_WIN32
271 static gchar *
272 inner_find_program_in_path (const gchar *program)
273 #else
274 gchar*
275 g_find_program_in_path (const gchar *program)
276 #endif
277 {
278   const gchar *path, *p;
279   gchar *name, *freeme;
280 #ifdef G_OS_WIN32
281   const gchar *path_copy;
282   gchar *filename = NULL, *appdir = NULL;
283   gchar *sysdir = NULL, *windir = NULL;
284   int n;
285   wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
286     wwindir[MAXPATHLEN];
287 #endif
288   gsize len;
289   gsize pathlen;
290
291   g_return_val_if_fail (program != NULL, NULL);
292
293   /* If it is an absolute path, or a relative path including subdirectories,
294    * don't look in PATH.
295    */
296   if (g_path_is_absolute (program)
297       || strchr (program, G_DIR_SEPARATOR) != NULL
298 #ifdef G_OS_WIN32
299       || strchr (program, '/') != NULL
300 #endif
301       )
302     {
303       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
304           !g_file_test (program, G_FILE_TEST_IS_DIR))
305         {
306           gchar *out = NULL, *cwd = NULL;
307
308           if (g_path_is_absolute (program))
309             return g_strdup (program);
310
311           cwd = g_get_current_dir ();
312           out = g_build_filename (cwd, program, NULL);
313           g_free (cwd);
314           return g_steal_pointer (&out);
315         }
316       else
317         return NULL;
318     }
319   
320   path = g_getenv ("PATH");
321 #if defined(G_OS_UNIX)
322   if (path == NULL)
323     {
324       /* There is no 'PATH' in the environment.  The default
325        * search path in GNU libc is the current directory followed by
326        * the path 'confstr' returns for '_CS_PATH'.
327        */
328       
329       /* In GLib we put . last, for security, and don't use the
330        * unportable confstr(); UNIX98 does not actually specify
331        * what to search if PATH is unset. POSIX may, dunno.
332        */
333       
334       path = "/bin:/usr/bin:.";
335     }
336 #else
337   n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
338   if (n > 0 && n < MAXPATHLEN)
339     filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
340   
341   n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
342   if (n > 0 && n < MAXPATHLEN)
343     sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
344   
345   n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
346   if (n > 0 && n < MAXPATHLEN)
347     windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
348   
349   if (filename)
350     {
351       appdir = g_path_get_dirname (filename);
352       g_free (filename);
353     }
354   
355   path = g_strdup (path);
356
357   if (windir)
358     {
359       const gchar *tem = path;
360       path = g_strconcat (windir, ";", path, NULL);
361       g_free ((gchar *) tem);
362       g_free (windir);
363     }
364   
365   if (sysdir)
366     {
367       const gchar *tem = path;
368       path = g_strconcat (sysdir, ";", path, NULL);
369       g_free ((gchar *) tem);
370       g_free (sysdir);
371     }
372   
373   {
374     const gchar *tem = path;
375     path = g_strconcat (".;", path, NULL);
376     g_free ((gchar *) tem);
377   }
378   
379   if (appdir)
380     {
381       const gchar *tem = path;
382       path = g_strconcat (appdir, ";", path, NULL);
383       g_free ((gchar *) tem);
384       g_free (appdir);
385     }
386
387   path_copy = path;
388 #endif
389   
390   len = strlen (program) + 1;
391   pathlen = strlen (path);
392   freeme = name = g_malloc (pathlen + len + 1);
393   
394   /* Copy the file name at the top, including '\0'  */
395   memcpy (name + pathlen + 1, program, len);
396   name = name + pathlen;
397   /* And add the slash before the filename  */
398   *name = G_DIR_SEPARATOR;
399   
400   p = path;
401   do
402     {
403       char *startp;
404
405       path = p;
406       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
407
408       if (p == path)
409         /* Two adjacent colons, or a colon at the beginning or the end
410          * of 'PATH' means to search the current directory.
411          */
412         startp = name + 1;
413       else
414         startp = memcpy (name - (p - path), path, p - path);
415
416       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
417           !g_file_test (startp, G_FILE_TEST_IS_DIR))
418         {
419           gchar *ret;
420           if (g_path_is_absolute (startp)) {
421             ret = g_strdup (startp);
422           } else {
423             gchar *cwd = NULL;
424             cwd = g_get_current_dir ();
425             ret = g_build_filename (cwd, startp, NULL);
426             g_free (cwd);
427           }
428           g_free (freeme);
429 #ifdef G_OS_WIN32
430           g_free ((gchar *) path_copy);
431 #endif
432           return ret;
433         }
434     }
435   while (*p++ != '\0');
436   
437   g_free (freeme);
438 #ifdef G_OS_WIN32
439   g_free ((gchar *) path_copy);
440 #endif
441
442   return NULL;
443 }
444
445 /* The functions below are defined this way for compatibility reasons.
446  * See the note in gutils.h.
447  */
448
449 /**
450  * g_bit_nth_lsf:
451  * @mask: a #gulong containing flags
452  * @nth_bit: the index of the bit to start the search from
453  *
454  * Find the position of the first bit set in @mask, searching
455  * from (but not including) @nth_bit upwards. Bits are numbered
456  * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63,
457  * usually). To start searching from the 0th bit, set @nth_bit to -1.
458  *
459  * Returns: the index of the first bit set which is higher than @nth_bit, or -1
460  *    if no higher bits are set
461  */
462 gint
463 (g_bit_nth_lsf) (gulong mask,
464                  gint   nth_bit)
465 {
466   return g_bit_nth_lsf_impl (mask, nth_bit);
467 }
468
469 /**
470  * g_bit_nth_msf:
471  * @mask: a #gulong containing flags
472  * @nth_bit: the index of the bit to start the search from
473  *
474  * Find the position of the first bit set in @mask, searching
475  * from (but not including) @nth_bit downwards. Bits are numbered
476  * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63,
477  * usually). To start searching from the last bit, set @nth_bit to
478  * -1 or GLIB_SIZEOF_LONG * 8.
479  *
480  * Returns: the index of the first bit set which is lower than @nth_bit, or -1
481  *    if no lower bits are set
482  */
483 gint
484 (g_bit_nth_msf) (gulong mask,
485                  gint   nth_bit)
486 {
487   return g_bit_nth_msf_impl (mask, nth_bit);
488 }
489
490
491 /**
492  * g_bit_storage:
493  * @number: a #guint
494  *
495  * Gets the number of bits used to hold @number,
496  * e.g. if @number is 4, 3 bits are needed.
497  *
498  * Returns: the number of bits used to hold @number
499  */
500 guint
501 (g_bit_storage) (gulong number)
502 {
503   return g_bit_storage_impl (number);
504 }
505
506 G_LOCK_DEFINE_STATIC (g_utils_global);
507
508 typedef struct
509 {
510   gchar *user_name;
511   gchar *real_name;
512   gchar *home_dir;
513 } UserDatabaseEntry;
514
515 /* These must all be read/written with @g_utils_global held. */
516 static  gchar   *g_user_data_dir = NULL;
517 static  gchar  **g_system_data_dirs = NULL;
518 static  gchar   *g_user_cache_dir = NULL;
519 static  gchar   *g_user_config_dir = NULL;
520 static  gchar   *g_user_state_dir = NULL;
521 static  gchar   *g_user_runtime_dir = NULL;
522 static  gchar  **g_system_config_dirs = NULL;
523 static  gchar  **g_user_special_dirs = NULL;
524
525 /* fifteen minutes of fame for everybody */
526 #define G_USER_DIRS_EXPIRE      15 * 60
527
528 #ifdef G_OS_WIN32
529
530 static gchar *
531 get_special_folder (REFKNOWNFOLDERID known_folder_guid_ptr)
532 {
533   wchar_t *wcp = NULL;
534   gchar *result = NULL;
535   HRESULT hr;
536
537   hr = SHGetKnownFolderPath (known_folder_guid_ptr, 0, NULL, &wcp);
538
539   if (SUCCEEDED (hr))
540     result = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
541
542   CoTaskMemFree (wcp);
543
544   return result;
545 }
546
547 static char *
548 get_windows_directory_root (void)
549 {
550   wchar_t wwindowsdir[MAX_PATH];
551
552   if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir)))
553     {
554       /* Usually X:\Windows, but in terminal server environments
555        * might be an UNC path, AFAIK.
556        */
557       char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL);
558       char *p;
559
560       if (windowsdir == NULL)
561         return g_strdup ("C:\\");
562
563       p = (char *) g_path_skip_root (windowsdir);
564       if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':')
565         p--;
566       *p = '\0';
567       return windowsdir;
568     }
569   else
570     return g_strdup ("C:\\");
571 }
572
573 #endif
574
575 /* HOLDS: g_utils_global_lock */
576 static UserDatabaseEntry *
577 g_get_user_database_entry (void)
578 {
579   static UserDatabaseEntry *entry;
580
581   if (g_once_init_enter (&entry))
582     {
583       static UserDatabaseEntry e;
584
585 #ifdef G_OS_UNIX
586       {
587         struct passwd *pw = NULL;
588         gpointer buffer = NULL;
589         gint error;
590         gchar *logname;
591
592 #  if defined (HAVE_GETPWUID_R)
593         struct passwd pwd;
594 #    ifdef _SC_GETPW_R_SIZE_MAX
595         /* This reurns the maximum length */
596         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
597
598         if (bufsize < 0)
599           bufsize = 64;
600 #    else /* _SC_GETPW_R_SIZE_MAX */
601         glong bufsize = 64;
602 #    endif /* _SC_GETPW_R_SIZE_MAX */
603
604         logname = (gchar *) g_getenv ("LOGNAME");
605
606         do
607           {
608             g_free (buffer);
609             /* we allocate 6 extra bytes to work around a bug in
610              * Mac OS < 10.3. See #156446
611              */
612             buffer = g_malloc (bufsize + 6);
613             errno = 0;
614
615             if (logname) {
616               error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw);
617               if (!pw || (pw->pw_uid != getuid ())) {
618                 /* LOGNAME is lying, fall back to looking up the uid */
619                 error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
620               }
621             } else {
622               error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
623             }
624             error = error < 0 ? errno : error;
625
626             if (!pw)
627               {
628                 /* we bail out prematurely if the user id can't be found
629                  * (should be pretty rare case actually), or if the buffer
630                  * should be sufficiently big and lookups are still not
631                  * successful.
632                  */
633                 if (error == 0 || error == ENOENT)
634                   {
635                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
636                                (gulong) getuid ());
637                     break;
638                   }
639                 if (bufsize > 32 * 1024)
640                   {
641                     g_warning ("getpwuid_r(): failed due to: %s.",
642                                g_strerror (error));
643                     break;
644                   }
645
646                 bufsize *= 2;
647               }
648           }
649         while (!pw);
650 #  endif /* HAVE_GETPWUID_R */
651
652         if (!pw)
653           {
654             pw = getpwuid (getuid ());
655           }
656         if (pw)
657           {
658             e.user_name = g_strdup (pw->pw_name);
659
660 #ifndef __BIONIC__
661             if (pw->pw_gecos && *pw->pw_gecos != '\0' && pw->pw_name)
662               {
663                 gchar **gecos_fields;
664                 gchar **name_parts;
665                 gchar *uppercase_pw_name;
666
667                 /* split the gecos field and substitute '&' */
668                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
669                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
670                 uppercase_pw_name = g_strdup (pw->pw_name);
671                 uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]);
672                 e.real_name = g_strjoinv (uppercase_pw_name, name_parts);
673                 g_strfreev (gecos_fields);
674                 g_strfreev (name_parts);
675                 g_free (uppercase_pw_name);
676               }
677 #endif
678
679             if (!e.home_dir)
680               e.home_dir = g_strdup (pw->pw_dir);
681           }
682         g_free (buffer);
683       }
684
685 #endif /* G_OS_UNIX */
686
687 #ifdef G_OS_WIN32
688       {
689         guint len = UNLEN+1;
690         wchar_t buffer[UNLEN+1];
691
692         if (GetUserNameW (buffer, (LPDWORD) &len))
693           {
694             e.user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
695             e.real_name = g_strdup (e.user_name);
696           }
697       }
698 #endif /* G_OS_WIN32 */
699
700       if (!e.user_name)
701         e.user_name = g_strdup ("somebody");
702       if (!e.real_name)
703         e.real_name = g_strdup ("Unknown");
704
705       g_once_init_leave (&entry, &e);
706     }
707
708   return entry;
709 }
710
711 /**
712  * g_get_user_name:
713  *
714  * Gets the user name of the current user. The encoding of the returned
715  * string is system-defined. On UNIX, it might be the preferred file name
716  * encoding, or something else, and there is no guarantee that it is even
717  * consistent on a machine. On Windows, it is always UTF-8.
718  *
719  * Returns: (type filename) (transfer none): the user name of the current user.
720  */
721 const gchar *
722 g_get_user_name (void)
723 {
724   UserDatabaseEntry *entry;
725
726   entry = g_get_user_database_entry ();
727
728   return entry->user_name;
729 }
730
731 /**
732  * g_get_real_name:
733  *
734  * Gets the real name of the user. This usually comes from the user's
735  * entry in the `passwd` file. The encoding of the returned string is
736  * system-defined. (On Windows, it is, however, always UTF-8.) If the
737  * real user name cannot be determined, the string "Unknown" is 
738  * returned.
739  *
740  * Returns: (type filename) (transfer none): the user's real name.
741  */
742 const gchar *
743 g_get_real_name (void)
744 {
745   UserDatabaseEntry *entry;
746
747   entry = g_get_user_database_entry ();
748
749   return entry->real_name;
750 }
751
752 /* Protected by @g_utils_global_lock. */
753 static gchar *g_home_dir = NULL;  /* (owned) (nullable before initialised) */
754
755 static gchar *
756 g_build_home_dir (void)
757 {
758   gchar *home_dir;
759
760   /* We first check HOME and use it if it is set */
761   home_dir = g_strdup (g_getenv ("HOME"));
762
763 #ifdef G_OS_WIN32
764   /* Only believe HOME if it is an absolute path and exists.
765    *
766    * We only do this check on Windows for a couple of reasons.
767    * Historically, we only did it there because we used to ignore $HOME
768    * on UNIX.  There are concerns about enabling it now on UNIX because
769    * of things like autofs.  In short, if the user has a bogus value in
770    * $HOME then they get what they pay for...
771    */
772   if (home_dir != NULL)
773     {
774       if (!(g_path_is_absolute (home_dir) &&
775             g_file_test (home_dir, G_FILE_TEST_IS_DIR)))
776         g_clear_pointer (&home_dir, g_free);
777     }
778
779   /* In case HOME is Unix-style (it happens), convert it to
780    * Windows style.
781    */
782   if (home_dir != NULL)
783     {
784       gchar *p;
785       while ((p = strchr (home_dir, '/')) != NULL)
786         *p = '\\';
787     }
788
789   if (home_dir == NULL)
790     {
791       /* USERPROFILE is probably the closest equivalent to $HOME? */
792       if (g_getenv ("USERPROFILE") != NULL)
793         home_dir = g_strdup (g_getenv ("USERPROFILE"));
794     }
795
796   if (home_dir == NULL)
797     home_dir = get_special_folder (&FOLDERID_Profile);
798
799   if (home_dir == NULL)
800     home_dir = get_windows_directory_root ();
801 #endif /* G_OS_WIN32 */
802
803   if (home_dir == NULL)
804     {
805       /* If we didn't get it from any of those methods, we will have
806        * to read the user database entry.
807        */
808       UserDatabaseEntry *entry = g_get_user_database_entry ();
809       home_dir = g_strdup (entry->home_dir);
810     }
811
812   /* If we have been denied access to /etc/passwd (for example, by an
813    * overly-zealous LSM), make up a junk value. The return value at this
814    * point is explicitly documented as â€˜undefined’. */
815   if (home_dir == NULL)
816     {
817       g_warning ("Could not find home directory: $HOME is not set, and "
818                  "user database could not be read.");
819       home_dir = g_strdup ("/");
820     }
821
822   return g_steal_pointer (&home_dir);
823 }
824
825 /**
826  * g_get_home_dir:
827  *
828  * Gets the current user's home directory.
829  *
830  * As with most UNIX tools, this function will return the value of the
831  * `HOME` environment variable if it is set to an existing absolute path
832  * name, falling back to the `passwd` file in the case that it is unset.
833  *
834  * If the path given in `HOME` is non-absolute, does not exist, or is
835  * not a directory, the result is undefined.
836  *
837  * Before version 2.36 this function would ignore the `HOME` environment
838  * variable, taking the value from the `passwd` database instead. This was
839  * changed to increase the compatibility of GLib with other programs (and
840  * the XDG basedir specification) and to increase testability of programs
841  * based on GLib (by making it easier to run them from test frameworks).
842  *
843  * If your program has a strong requirement for either the new or the
844  * old behaviour (and if you don't wish to increase your GLib
845  * dependency to ensure that the new behaviour is in effect) then you
846  * should either directly check the `HOME` environment variable yourself
847  * or unset it before calling any functions in GLib.
848  *
849  * Returns: (type filename) (transfer none): the current user's home directory
850  */
851 const gchar *
852 g_get_home_dir (void)
853 {
854   const gchar *home_dir;
855
856   G_LOCK (g_utils_global);
857
858   if (g_home_dir == NULL)
859     g_home_dir = g_build_home_dir ();
860   home_dir = g_home_dir;
861
862   G_UNLOCK (g_utils_global);
863
864   return home_dir;
865 }
866
867 /**
868  * g_get_tmp_dir:
869  *
870  * Gets the directory to use for temporary files.
871  *
872  * On UNIX, this is taken from the `TMPDIR` environment variable.
873  * If the variable is not set, `P_tmpdir` is
874  * used, as defined by the system C library. Failing that, a
875  * hard-coded default of "/tmp" is returned.
876  *
877  * On Windows, the `TEMP` environment variable is used, with the
878  * root directory of the Windows installation (eg: "C:\") used
879  * as a default.
880  *
881  * The encoding of the returned string is system-defined. On Windows,
882  * it is always UTF-8. The return value is never %NULL or the empty
883  * string.
884  *
885  * Returns: (type filename) (transfer none): the directory to use for temporary files.
886  */
887 const gchar *
888 g_get_tmp_dir (void)
889 {
890   static gchar *tmp_dir;
891
892   if (g_once_init_enter (&tmp_dir))
893     {
894       gchar *tmp;
895
896 #ifdef G_OS_WIN32
897       tmp = g_strdup (g_getenv ("TEMP"));
898
899       if (tmp == NULL || *tmp == '\0')
900         {
901           g_free (tmp);
902           tmp = get_windows_directory_root ();
903         }
904 #else /* G_OS_WIN32 */
905       tmp = g_strdup (g_getenv ("TMPDIR"));
906
907 #ifdef P_tmpdir
908       if (tmp == NULL || *tmp == '\0')
909         {
910           gsize k;
911           g_free (tmp);
912           tmp = g_strdup (P_tmpdir);
913           k = strlen (tmp);
914           if (k > 1 && G_IS_DIR_SEPARATOR (tmp[k - 1]))
915             tmp[k - 1] = '\0';
916         }
917 #endif /* P_tmpdir */
918
919       if (tmp == NULL || *tmp == '\0')
920         {
921           g_free (tmp);
922           tmp = g_strdup ("/tmp");
923         }
924 #endif /* !G_OS_WIN32 */
925
926       g_once_init_leave (&tmp_dir, tmp);
927     }
928
929   return tmp_dir;
930 }
931
932 /**
933  * g_get_host_name:
934  *
935  * Return a name for the machine. 
936  *
937  * The returned name is not necessarily a fully-qualified domain name,
938  * or even present in DNS or some other name service at all. It need
939  * not even be unique on your local network or site, but usually it
940  * is. Callers should not rely on the return value having any specific
941  * properties like uniqueness for security purposes. Even if the name
942  * of the machine is changed while an application is running, the
943  * return value from this function does not change. The returned
944  * string is owned by GLib and should not be modified or freed. If no
945  * name can be determined, a default fixed string "localhost" is
946  * returned.
947  *
948  * The encoding of the returned string is UTF-8.
949  *
950  * Returns: (transfer none): the host name of the machine.
951  *
952  * Since: 2.8
953  */
954 const gchar *
955 g_get_host_name (void)
956 {
957   static gchar *hostname;
958
959   if (g_once_init_enter (&hostname))
960     {
961       gboolean failed;
962       gchar *utmp = NULL;
963
964 #ifndef G_OS_WIN32
965       gsize size;
966       /* The number 256 * 256 is taken from the value of _POSIX_HOST_NAME_MAX,
967        * which is 255. Since we use _POSIX_HOST_NAME_MAX + 1 (= 256) in the
968        * fallback case, we pick 256 * 256 as the size of the larger buffer here.
969        * It should be large enough. It doesn't looks reasonable to name a host
970        * with a string that is longer than 64 KiB.
971        */
972       const gsize size_large = (gsize) 256 * 256;
973       gchar *tmp;
974
975 #ifdef _SC_HOST_NAME_MAX
976       {
977         glong max;
978
979         max = sysconf (_SC_HOST_NAME_MAX);
980         if (max > 0 && (gsize) max <= G_MAXSIZE - 1)
981           size = (gsize) max + 1;
982         else
983 #ifdef HOST_NAME_MAX
984           size = HOST_NAME_MAX + 1;
985 #else
986           size = _POSIX_HOST_NAME_MAX + 1;
987 #endif /* HOST_NAME_MAX */
988       }
989 #else
990       /* Fallback to some reasonable value */
991       size = 256;
992 #endif /* _SC_HOST_NAME_MAX */
993       tmp = g_malloc (size);
994       failed = (gethostname (tmp, size) == -1);
995       if (failed && size < size_large)
996         {
997           /* Try again with a larger buffer if 'size' may be too small. */
998           g_free (tmp);
999           tmp = g_malloc (size_large);
1000           failed = (gethostname (tmp, size_large) == -1);
1001         }
1002
1003       if (failed)
1004         g_clear_pointer (&tmp, g_free);
1005       utmp = tmp;
1006 #else
1007       wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
1008       DWORD size = sizeof (tmp) / sizeof (tmp[0]);
1009       failed = (!GetComputerNameW (tmp, &size));
1010       if (!failed)
1011         utmp = g_utf16_to_utf8 (tmp, size, NULL, NULL, NULL);
1012       if (utmp == NULL)
1013         failed = TRUE;
1014 #endif
1015
1016       g_once_init_leave (&hostname, failed ? g_strdup ("localhost") : utmp);
1017     }
1018
1019   return hostname;
1020 }
1021
1022 G_LOCK_DEFINE_STATIC (g_prgname);
1023 static const gchar *g_prgname = NULL; /* always a quark */
1024
1025 /**
1026  * g_get_prgname:
1027  *
1028  * Gets the name of the program. This name should not be localized,
1029  * in contrast to g_get_application_name().
1030  *
1031  * If you are using #GApplication the program name is set in
1032  * g_application_run(). In case of GDK or GTK+ it is set in
1033  * gdk_init(), which is called by gtk_init() and the
1034  * #GtkApplication::startup handler. The program name is found by
1035  * taking the last component of @argv[0].
1036  *
1037  * Returns: (nullable) (transfer none): the name of the program,
1038  *   or %NULL if it has not been set yet. The returned string belongs
1039  *   to GLib and must not be modified or freed.
1040  */
1041 const gchar*
1042 g_get_prgname (void)
1043 {
1044   const gchar* retval;
1045
1046   G_LOCK (g_prgname);
1047   retval = g_prgname;
1048   G_UNLOCK (g_prgname);
1049
1050   return retval;
1051 }
1052
1053 /**
1054  * g_set_prgname:
1055  * @prgname: the name of the program.
1056  *
1057  * Sets the name of the program. This name should not be localized,
1058  * in contrast to g_set_application_name().
1059  *
1060  * If you are using #GApplication the program name is set in
1061  * g_application_run(). In case of GDK or GTK+ it is set in
1062  * gdk_init(), which is called by gtk_init() and the
1063  * #GtkApplication::startup handler. The program name is found by
1064  * taking the last component of @argv[0].
1065  *
1066  * Since GLib 2.72, this function can be called multiple times
1067  * and is fully thread safe. Prior to GLib 2.72, this function
1068  * could only be called once per process.
1069  */
1070 void
1071 g_set_prgname (const gchar *prgname)
1072 {
1073   GQuark qprgname = g_quark_from_string (prgname);
1074   G_LOCK (g_prgname);
1075   g_prgname = g_quark_to_string (qprgname);
1076   G_UNLOCK (g_prgname);
1077 }
1078
1079 G_LOCK_DEFINE_STATIC (g_application_name);
1080 static gchar *g_application_name = NULL;
1081
1082 /**
1083  * g_get_application_name:
1084  * 
1085  * Gets a human-readable name for the application, as set by
1086  * g_set_application_name(). This name should be localized if
1087  * possible, and is intended for display to the user.  Contrast with
1088  * g_get_prgname(), which gets a non-localized name. If
1089  * g_set_application_name() has not been called, returns the result of
1090  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1091  * been called).
1092  * 
1093  * Returns: (transfer none) (nullable): human-readable application
1094  *   name. May return %NULL
1095  *
1096  * Since: 2.2
1097  **/
1098 const gchar *
1099 g_get_application_name (void)
1100 {
1101   gchar* retval;
1102
1103   G_LOCK (g_application_name);
1104   retval = g_application_name;
1105   G_UNLOCK (g_application_name);
1106
1107   if (retval == NULL)
1108     return g_get_prgname ();
1109   
1110   return retval;
1111 }
1112
1113 /**
1114  * g_set_application_name:
1115  * @application_name: localized name of the application
1116  *
1117  * Sets a human-readable name for the application. This name should be
1118  * localized if possible, and is intended for display to the user.
1119  * Contrast with g_set_prgname(), which sets a non-localized name.
1120  * g_set_prgname() will be called automatically by gtk_init(),
1121  * but g_set_application_name() will not.
1122  *
1123  * Note that for thread safety reasons, this function can only
1124  * be called once.
1125  *
1126  * The application name will be used in contexts such as error messages,
1127  * or when displaying an application's name in the task list.
1128  * 
1129  * Since: 2.2
1130  **/
1131 void
1132 g_set_application_name (const gchar *application_name)
1133 {
1134   gboolean already_set = FALSE;
1135         
1136   G_LOCK (g_application_name);
1137   if (g_application_name)
1138     already_set = TRUE;
1139   else
1140     g_application_name = g_strdup (application_name);
1141   G_UNLOCK (g_application_name);
1142
1143   if (already_set)
1144     g_warning ("g_set_application_name() called multiple times");
1145 }
1146
1147 #ifdef G_OS_WIN32
1148 /* For the past versions we can just
1149  * hardcode all the names.
1150  */
1151 static const struct winver
1152 {
1153   gint major;
1154   gint minor;
1155   gint sp;
1156   const char *version;
1157   const char *spversion;
1158 } versions[] =
1159 {
1160   {6, 2, 0, "8", ""},
1161   {6, 1, 1, "7", " SP1"},
1162   {6, 1, 0, "7", ""},
1163   {6, 0, 2, "Vista", " SP2"},
1164   {6, 0, 1, "Vista", " SP1"},
1165   {6, 0, 0, "Vista", ""},
1166   {5, 1, 3, "XP", " SP3"},
1167   {5, 1, 2, "XP", " SP2"},
1168   {5, 1, 1, "XP", " SP1"},
1169   {5, 1, 0, "XP", ""},
1170   {0, 0, 0, NULL, NULL},
1171 };
1172
1173 static gchar *
1174 get_registry_str (HKEY root_key, const wchar_t *path, const wchar_t *value_name)
1175 {
1176   HKEY key_handle;
1177   DWORD req_value_data_size;
1178   DWORD req_value_data_size2;
1179   LONG status;
1180   DWORD value_type_w;
1181   DWORD value_type_w2;
1182   char *req_value_data;
1183   gchar *result;
1184
1185   status = RegOpenKeyExW (root_key, path, 0, KEY_READ, &key_handle);
1186   if (status != ERROR_SUCCESS)
1187     return NULL;
1188
1189   req_value_data_size = 0;
1190   status = RegQueryValueExW (key_handle,
1191                              value_name,
1192                              NULL,
1193                              &value_type_w,
1194                              NULL,
1195                              &req_value_data_size);
1196
1197   if (status != ERROR_MORE_DATA && status != ERROR_SUCCESS)
1198     {
1199       RegCloseKey (key_handle);
1200
1201       return NULL;
1202     }
1203
1204   req_value_data = g_malloc (req_value_data_size);
1205   req_value_data_size2 = req_value_data_size;
1206
1207   status = RegQueryValueExW (key_handle,
1208                              value_name,
1209                              NULL,
1210                              &value_type_w2,
1211                              (gpointer) req_value_data,
1212                              &req_value_data_size2);
1213
1214   result = NULL;
1215
1216   if (status == ERROR_SUCCESS && value_type_w2 == REG_SZ)
1217     result = g_utf16_to_utf8 ((gunichar2 *) req_value_data,
1218                               req_value_data_size / sizeof (gunichar2),
1219                               NULL,
1220                               NULL,
1221                               NULL);
1222
1223   g_free (req_value_data);
1224   RegCloseKey (key_handle);
1225
1226   return result;
1227 }
1228
1229 /* Windows 8.1 can be either plain or with Update 1,
1230  * depending on its build number (9200 or 9600).
1231  */
1232 static gchar *
1233 get_windows_8_1_update (void)
1234 {
1235   gchar *current_build;
1236   gchar *result = NULL;
1237
1238   current_build = get_registry_str (HKEY_LOCAL_MACHINE,
1239                                     L"SOFTWARE"
1240                                     L"\\Microsoft"
1241                                     L"\\Windows NT"
1242                                     L"\\CurrentVersion",
1243                                     L"CurrentBuild");
1244
1245   if (current_build != NULL)
1246     {
1247       wchar_t *end;
1248       long build = wcstol ((const wchar_t *) current_build, &end, 10);
1249
1250       if (build <= INT_MAX &&
1251           build >= INT_MIN &&
1252           errno == 0 &&
1253           *end == L'\0')
1254         {
1255           if (build >= 9600)
1256             result = g_strdup ("Update 1");
1257         }
1258     }
1259
1260   g_clear_pointer (&current_build, g_free);
1261
1262   return result;
1263 }
1264
1265 static gchar *
1266 get_windows_version (gboolean with_windows)
1267 {
1268   GString *version = g_string_new (NULL);
1269   gboolean is_win_server = FALSE;
1270
1271   if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
1272     {
1273       gchar *win10_release;
1274       gboolean is_win11 = FALSE;
1275       OSVERSIONINFOEXW osinfo;
1276
1277       /* Are we on Windows 2016/2019/2022 Server? */
1278       is_win_server = g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_SERVER);
1279
1280       /*
1281        * This always succeeds if we get here, since the
1282        * g_win32_check_windows_version() already did this!
1283        * We want the OSVERSIONINFOEXW here for more even
1284        * fine-grained versioning items
1285        */
1286       _g_win32_call_rtl_version (&osinfo);
1287
1288       if (!is_win_server)
1289         {
1290           /*
1291            * Windows 11 is actually Windows 10.0.22000+,
1292            * so look at the build number
1293            */
1294           is_win11 = (osinfo.dwBuildNumber >= 22000);
1295         }
1296       else
1297         {
1298           /*
1299            * Windows 2022 Server is actually Windows 10.0.20348+,
1300            * Windows 2019 Server is actually Windows 10.0.17763+,
1301            * Windows 2016 Server is actually Windows 10.0.14393+,
1302            * so look at the build number
1303            */
1304           g_string_append (version, "Server");
1305           if (osinfo.dwBuildNumber >= 20348)
1306             g_string_append (version, " 2022");
1307           else if (osinfo.dwBuildNumber >= 17763)
1308             g_string_append (version, " 2019");
1309           else
1310             g_string_append (version, " 2016");
1311         }
1312
1313       if (is_win11)
1314         g_string_append (version, "11");
1315       else if (!is_win_server)
1316         g_string_append (version, "10");
1317
1318       /* Windows 10/Server 2016+ is identified by its ReleaseId or
1319        * DisplayVersion (since 20H2), such as
1320        * 1511, 1607, 1703, 1709, 1803, 1809 or 1903 etc.
1321        * The first version of Windows 10 has no release number.
1322        */
1323       win10_release = get_registry_str (HKEY_LOCAL_MACHINE,
1324                                         L"SOFTWARE"
1325                                         L"\\Microsoft"
1326                                         L"\\Windows NT"
1327                                         L"\\CurrentVersion",
1328                                         L"ReleaseId");
1329
1330       if (win10_release != NULL)
1331         {
1332           if (g_strcmp0 (win10_release, "2009") != 0)
1333             g_string_append_printf (version, " %s", win10_release);
1334           else
1335             {
1336               g_free (win10_release);
1337
1338               win10_release = get_registry_str (HKEY_LOCAL_MACHINE,
1339                                                 L"SOFTWARE"
1340                                                 L"\\Microsoft"
1341                                                 L"\\Windows NT"
1342                                                 L"\\CurrentVersion",
1343                                                 L"DisplayVersion");
1344
1345               if (win10_release != NULL)
1346                 g_string_append_printf (version, " %s", win10_release);
1347               else
1348                 g_string_append_printf (version, " 2009");
1349             }
1350         }
1351
1352       g_free (win10_release);
1353     }
1354   else if (g_win32_check_windows_version (6, 3, 0, G_WIN32_OS_ANY))
1355     {
1356       gchar *win81_update;
1357
1358       if (g_win32_check_windows_version (6, 3, 0, G_WIN32_OS_WORKSTATION))
1359         g_string_append (version, "8.1");
1360       else
1361         g_string_append (version, "Server 2012 R2");
1362
1363       win81_update = get_windows_8_1_update ();
1364
1365       if (win81_update != NULL)
1366         g_string_append_printf (version, " %s", win81_update);
1367
1368       g_free (win81_update);
1369     }
1370   else
1371     {
1372       gint i;
1373
1374       for (i = 0; versions[i].major > 0; i++)
1375         {
1376           if (!g_win32_check_windows_version (versions[i].major, versions[i].minor, versions[i].sp, G_WIN32_OS_ANY))
1377             continue;
1378
1379           g_string_append (version, versions[i].version);
1380
1381           if (g_win32_check_windows_version (versions[i].major, versions[i].minor, versions[i].sp, G_WIN32_OS_SERVER))
1382             {
1383               /*
1384                * This condition should now always hold, since Windows
1385                * 7+/Server 2008 R2+ is now required
1386                */
1387               if (versions[i].major == 6)
1388                 {
1389                   g_string_append (version, "Server");
1390                   if (versions[i].minor == 2)
1391                     g_string_append (version, " 2012");
1392                   else if (versions[i].minor == 1)
1393                     g_string_append (version, " 2008 R2");
1394                   else
1395                     g_string_append (version, " 2008");
1396                 }
1397             }
1398
1399           g_string_append (version, versions[i].spversion);
1400         }
1401     }
1402
1403   if (version->len == 0)
1404     {
1405       g_string_free (version, TRUE);
1406
1407       return NULL;
1408     }
1409
1410   if (with_windows)
1411     g_string_prepend (version, "Windows ");
1412
1413   return g_string_free (version, FALSE);
1414 }
1415 #endif
1416
1417 #if defined (G_OS_UNIX) && !defined (__APPLE__)
1418 static gchar *
1419 get_os_info_from_os_release (const gchar *key_name,
1420                              const gchar *buffer)
1421 {
1422   GStrv lines;
1423   gchar *prefix;
1424   size_t i;
1425   gchar *result = NULL;
1426
1427   lines = g_strsplit (buffer, "\n", -1);
1428   prefix = g_strdup_printf ("%s=", key_name);
1429   for (i = 0; lines[i] != NULL; i++)
1430     {
1431       const gchar *line = lines[i];
1432       const gchar *value;
1433
1434       if (g_str_has_prefix (line, prefix))
1435         {
1436           value = line + strlen (prefix);
1437           result = g_shell_unquote (value, NULL);
1438           if (result == NULL)
1439             result = g_strdup (value);
1440           break;
1441         }
1442     }
1443   g_strfreev (lines);
1444   g_free (prefix);
1445
1446 #ifdef __linux__
1447   /* Default values in spec */
1448   if (result == NULL)
1449     {
1450       if (g_str_equal (key_name, G_OS_INFO_KEY_NAME))
1451         return g_strdup ("Linux");
1452       if (g_str_equal (key_name, G_OS_INFO_KEY_ID))
1453         return g_strdup ("linux");
1454       if (g_str_equal (key_name, G_OS_INFO_KEY_PRETTY_NAME))
1455         return g_strdup ("Linux");
1456     }
1457 #endif
1458
1459   return g_steal_pointer (&result);
1460 }
1461
1462 static gchar *
1463 get_os_info_from_uname (const gchar *key_name)
1464 {
1465   struct utsname info;
1466
1467   if (uname (&info) == -1)
1468     return NULL;
1469
1470   if (strcmp (key_name, G_OS_INFO_KEY_NAME) == 0)
1471     return g_strdup (info.sysname);
1472   else if (strcmp (key_name, G_OS_INFO_KEY_VERSION) == 0)
1473     return g_strdup (info.release);
1474   else if (strcmp (key_name, G_OS_INFO_KEY_PRETTY_NAME) == 0)
1475     return g_strdup_printf ("%s %s", info.sysname, info.release);
1476   else if (strcmp (key_name, G_OS_INFO_KEY_ID) == 0)
1477     {
1478       gchar *result = g_ascii_strdown (info.sysname, -1);
1479
1480       g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1481       return g_steal_pointer (&result);
1482     }
1483   else if (strcmp (key_name, G_OS_INFO_KEY_VERSION_ID) == 0)
1484     {
1485       /* We attempt to convert the version string to the format returned by
1486        * config.guess, which is the script used to generate target triplets
1487        * in GNU autotools. There are a lot of rules in the script. We only
1488        * implement a few rules which are easy to understand here.
1489        *
1490        * config.guess can be found at https://savannah.gnu.org/projects/config.
1491        */
1492       gchar *result;
1493
1494       if (strcmp (info.sysname, "NetBSD") == 0)
1495         {
1496           /* sed -e 's,[-_].*,,' */
1497           gssize len = G_MAXSSIZE;
1498           const gchar *c;
1499
1500           if ((c = strchr (info.release, '-')) != NULL)
1501             len = MIN (len, c - info.release);
1502           if ((c = strchr (info.release, '_')) != NULL)
1503             len = MIN (len, c - info.release);
1504           if (len == G_MAXSSIZE)
1505             len = -1;
1506
1507           result = g_ascii_strdown (info.release, len);
1508         }
1509       else if (strcmp (info.sysname, "GNU") == 0)
1510         {
1511           /* sed -e 's,/.*$,,' */
1512           gssize len = -1;
1513           const gchar *c = strchr (info.release, '/');
1514
1515           if (c != NULL)
1516             len = c - info.release;
1517
1518           result = g_ascii_strdown (info.release, len);
1519         }
1520       else if (g_str_has_prefix (info.sysname, "GNU/") ||
1521                strcmp (info.sysname, "FreeBSD") == 0 ||
1522                strcmp (info.sysname, "DragonFly") == 0)
1523         {
1524           /* sed -e 's,[-(].*,,' */
1525           gssize len = G_MAXSSIZE;
1526           const gchar *c;
1527
1528           if ((c = strchr (info.release, '-')) != NULL)
1529             len = MIN (len, c - info.release);
1530           if ((c = strchr (info.release, '(')) != NULL)
1531             len = MIN (len, c - info.release);
1532           if (len == G_MAXSSIZE)
1533             len = -1;
1534
1535           result = g_ascii_strdown (info.release, len);
1536         }
1537       else
1538         result = g_ascii_strdown (info.release, -1);
1539
1540       g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1541       return g_steal_pointer (&result);
1542     }
1543   else
1544     return NULL;
1545 }
1546 #endif  /* defined (G_OS_UNIX) && !defined (__APPLE__) */
1547
1548 /**
1549  * g_get_os_info:
1550  * @key_name: a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
1551  *
1552  * Get information about the operating system.
1553  *
1554  * On Linux this comes from the `/etc/os-release` file. On other systems, it may
1555  * come from a variety of sources. You can either use the standard key names
1556  * like %G_OS_INFO_KEY_NAME or pass any UTF-8 string key name. For example,
1557  * `/etc/os-release` provides a number of other less commonly used values that may
1558  * be useful. No key is guaranteed to be provided, so the caller should always
1559  * check if the result is %NULL.
1560  *
1561  * Returns: (nullable): The associated value for the requested key or %NULL if
1562  *   this information is not provided.
1563  *
1564  * Since: 2.64
1565  **/
1566 gchar *
1567 g_get_os_info (const gchar *key_name)
1568 {
1569 #if defined (__APPLE__)
1570   if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
1571     return g_strdup ("macOS");
1572   else
1573     return NULL;
1574 #elif defined (G_OS_UNIX)
1575   const gchar * const os_release_files[] = { "/etc/os-release", "/usr/lib/os-release" };
1576   gsize i;
1577   gchar *buffer = NULL;
1578   gchar *result = NULL;
1579
1580   g_return_val_if_fail (key_name != NULL, NULL);
1581
1582   for (i = 0; i < G_N_ELEMENTS (os_release_files); i++)
1583     {
1584       GError *error = NULL;
1585       gboolean file_missing;
1586
1587       if (g_file_get_contents (os_release_files[i], &buffer, NULL, &error))
1588         break;
1589
1590       file_missing = g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
1591       g_clear_error (&error);
1592
1593       if (!file_missing)
1594         return NULL;
1595     }
1596
1597   if (buffer != NULL)
1598     result = get_os_info_from_os_release (key_name, buffer);
1599   else
1600     result = get_os_info_from_uname (key_name);
1601
1602   g_free (buffer);
1603   return g_steal_pointer (&result);
1604 #elif defined (G_OS_WIN32)
1605   if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
1606     return g_strdup ("Windows");
1607   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_ID) == 0)
1608     return g_strdup ("windows");
1609   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_PRETTY_NAME) == 0)
1610     /* Windows XP SP2 or Windows 10 1903 or Windows 7 Server SP1 */
1611     return get_windows_version (TRUE);
1612   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_VERSION) == 0)
1613     /* XP SP2 or 10 1903 or 7 Server SP1 */
1614     return get_windows_version (FALSE);
1615   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_VERSION_ID) == 0)
1616     {
1617       /* xp_sp2 or 10_1903 or 7_server_sp1 */
1618       gchar *result;
1619       gchar *version = get_windows_version (FALSE);
1620
1621       if (version == NULL)
1622         return NULL;
1623
1624       result = g_ascii_strdown (version, -1);
1625       g_free (version);
1626
1627       return g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1628     }
1629   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_HOME_URL) == 0)
1630     return g_strdup ("https://microsoft.com/windows/");
1631   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_DOCUMENTATION_URL) == 0)
1632     return g_strdup ("https://docs.microsoft.com/");
1633   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_SUPPORT_URL) == 0)
1634     return g_strdup ("https://support.microsoft.com/");
1635   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_BUG_REPORT_URL) == 0)
1636     return g_strdup ("https://support.microsoft.com/contactus/");
1637   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_PRIVACY_POLICY_URL) == 0)
1638     return g_strdup ("https://privacy.microsoft.com/");
1639   else
1640     return NULL;
1641 #endif
1642 }
1643
1644 /* Set @global_str to a copy of @new_value if it’s currently unset or has a
1645  * different value. If its current value matches @new_value, do nothing. If
1646  * replaced, we have to leak the old value as client code could still have
1647  * pointers to it. */
1648 static void
1649 set_str_if_different (gchar       **global_str,
1650                       const gchar  *type,
1651                       const gchar  *new_value)
1652 {
1653   if (*global_str == NULL ||
1654       !g_str_equal (new_value, *global_str))
1655     {
1656       g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value);
1657
1658       /* We have to leak the old value, as user code could be retaining pointers
1659        * to it. */
1660       g_ignore_leak (*global_str);
1661       *global_str = g_strdup (new_value);
1662     }
1663 }
1664
1665 static void
1666 set_strv_if_different (gchar                ***global_strv,
1667                        const gchar            *type,
1668                        const gchar  * const   *new_value)
1669 {
1670   if (*global_strv == NULL ||
1671       !g_strv_equal (new_value, (const gchar * const *) *global_strv))
1672     {
1673       gchar *new_value_str = g_strjoinv (":", (gchar **) new_value);
1674       g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value_str);
1675       g_free (new_value_str);
1676
1677       /* We have to leak the old value, as user code could be retaining pointers
1678        * to it. */
1679       g_ignore_strv_leak (*global_strv);
1680       *global_strv = g_strdupv ((gchar **) new_value);
1681     }
1682 }
1683
1684 /*
1685  * g_set_user_dirs:
1686  * @first_dir_type: Type of the first directory to set
1687  * @...: Value to set the first directory to, followed by additional type/value
1688  *    pairs, followed by %NULL
1689  *
1690  * Set one or more â€˜user’ directories to custom values. This is intended to be
1691  * used by test code (particularly with the %G_TEST_OPTION_ISOLATE_DIRS option)
1692  * to override the values returned by the following functions, so that test
1693  * code can be run without touching an installed system and user data:
1694  *
1695  *  - g_get_home_dir() â€” use type `HOME`, pass a string
1696  *  - g_get_user_cache_dir() â€” use type `XDG_CACHE_HOME`, pass a string
1697  *  - g_get_system_config_dirs() â€” use type `XDG_CONFIG_DIRS`, pass a
1698  *    %NULL-terminated string array
1699  *  - g_get_user_config_dir() â€” use type `XDG_CONFIG_HOME`, pass a string
1700  *  - g_get_system_data_dirs() â€” use type `XDG_DATA_DIRS`, pass a
1701  *    %NULL-terminated string array
1702  *  - g_get_user_data_dir() â€” use type `XDG_DATA_HOME`, pass a string
1703  *  - g_get_user_runtime_dir() â€” use type `XDG_RUNTIME_DIR`, pass a string
1704  *
1705  * The list must be terminated with a %NULL type. All of the values must be
1706  * non-%NULL â€” passing %NULL as a value won’t reset a directory. If a reference
1707  * to a directory from the calling environment needs to be kept, copy it before
1708  * the first call to g_set_user_dirs(). g_set_user_dirs() can be called multiple
1709  * times.
1710  *
1711  * Since: 2.60
1712  */
1713 /*< private > */
1714 void
1715 g_set_user_dirs (const gchar *first_dir_type,
1716                  ...)
1717 {
1718   va_list args;
1719   const gchar *dir_type;
1720
1721   G_LOCK (g_utils_global);
1722
1723   va_start (args, first_dir_type);
1724
1725   for (dir_type = first_dir_type; dir_type != NULL; dir_type = va_arg (args, const gchar *))
1726     {
1727       gconstpointer dir_value = va_arg (args, gconstpointer);
1728       g_assert (dir_value != NULL);
1729
1730       if (g_str_equal (dir_type, "HOME"))
1731         set_str_if_different (&g_home_dir, dir_type, dir_value);
1732       else if (g_str_equal (dir_type, "XDG_CACHE_HOME"))
1733         set_str_if_different (&g_user_cache_dir, dir_type, dir_value);
1734       else if (g_str_equal (dir_type, "XDG_CONFIG_DIRS"))
1735         set_strv_if_different (&g_system_config_dirs, dir_type, dir_value);
1736       else if (g_str_equal (dir_type, "XDG_CONFIG_HOME"))
1737         set_str_if_different (&g_user_config_dir, dir_type, dir_value);
1738       else if (g_str_equal (dir_type, "XDG_DATA_DIRS"))
1739         set_strv_if_different (&g_system_data_dirs, dir_type, dir_value);
1740       else if (g_str_equal (dir_type, "XDG_DATA_HOME"))
1741         set_str_if_different (&g_user_data_dir, dir_type, dir_value);
1742       else if (g_str_equal (dir_type, "XDG_STATE_HOME"))
1743         set_str_if_different (&g_user_state_dir, dir_type, dir_value);
1744       else if (g_str_equal (dir_type, "XDG_RUNTIME_DIR"))
1745         set_str_if_different (&g_user_runtime_dir, dir_type, dir_value);
1746       else
1747         g_assert_not_reached ();
1748     }
1749
1750   va_end (args);
1751
1752   G_UNLOCK (g_utils_global);
1753 }
1754
1755 static gchar *
1756 g_build_user_data_dir (void)
1757 {
1758   gchar *data_dir = NULL;
1759   const gchar *data_dir_env = g_getenv ("XDG_DATA_HOME");
1760
1761   if (data_dir_env && data_dir_env[0])
1762     data_dir = g_strdup (data_dir_env);
1763 #ifdef G_OS_WIN32
1764   else
1765     data_dir = get_special_folder (&FOLDERID_LocalAppData);
1766 #endif
1767   if (!data_dir || !data_dir[0])
1768     {
1769       gchar *home_dir = g_build_home_dir ();
1770       data_dir = g_build_filename (home_dir, ".local", "share", NULL);
1771       g_free (home_dir);
1772     }
1773
1774   return g_steal_pointer (&data_dir);
1775 }
1776
1777 /**
1778  * g_get_user_data_dir:
1779  * 
1780  * Returns a base directory in which to access application data such
1781  * as icons that is customized for a particular user.  
1782  *
1783  * On UNIX platforms this is determined using the mechanisms described
1784  * in the
1785  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1786  * In this case the directory retrieved will be `XDG_DATA_HOME`.
1787  *
1788  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
1789  * is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
1790  * opposed to roaming) application data is used instead. See the
1791  * [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
1792  * Note that in this case on Windows it will be the same
1793  * as what g_get_user_config_dir() returns.
1794  *
1795  * The return value is cached and modifying it at runtime is not supported, as
1796  * it’s not thread-safe to modify environment variables at runtime.
1797  *
1798  * Returns: (type filename) (transfer none): a string owned by GLib that must
1799  *   not be modified or freed.
1800  *
1801  * Since: 2.6
1802  **/
1803 const gchar *
1804 g_get_user_data_dir (void)
1805 {
1806   const gchar *user_data_dir;
1807
1808   G_LOCK (g_utils_global);
1809
1810   if (g_user_data_dir == NULL)
1811     g_user_data_dir = g_build_user_data_dir ();
1812   user_data_dir = g_user_data_dir;
1813
1814   G_UNLOCK (g_utils_global);
1815
1816   return user_data_dir;
1817 }
1818
1819 static gchar *
1820 g_build_user_config_dir (void)
1821 {
1822   gchar *config_dir = NULL;
1823   const gchar *config_dir_env = g_getenv ("XDG_CONFIG_HOME");
1824
1825   if (config_dir_env && config_dir_env[0])
1826     config_dir = g_strdup (config_dir_env);
1827 #ifdef G_OS_WIN32
1828   else
1829     config_dir = get_special_folder (&FOLDERID_LocalAppData);
1830 #endif
1831   if (!config_dir || !config_dir[0])
1832     {
1833       gchar *home_dir = g_build_home_dir ();
1834       config_dir = g_build_filename (home_dir, ".config", NULL);
1835       g_free (home_dir);
1836     }
1837
1838   return g_steal_pointer (&config_dir);
1839 }
1840
1841 /**
1842  * g_get_user_config_dir:
1843  * 
1844  * Returns a base directory in which to store user-specific application 
1845  * configuration information such as user preferences and settings. 
1846  *
1847  * On UNIX platforms this is determined using the mechanisms described
1848  * in the
1849  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1850  * In this case the directory retrieved will be `XDG_CONFIG_HOME`.
1851  *
1852  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
1853  * If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
1854  * to roaming) application data is used instead. See the
1855  * [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
1856  * Note that in this case on Windows it will be  the same
1857  * as what g_get_user_data_dir() returns.
1858  *
1859  * The return value is cached and modifying it at runtime is not supported, as
1860  * it’s not thread-safe to modify environment variables at runtime.
1861  *
1862  * Returns: (type filename) (transfer none): a string owned by GLib that
1863  *   must not be modified or freed.
1864  * Since: 2.6
1865  **/
1866 const gchar *
1867 g_get_user_config_dir (void)
1868 {
1869   const gchar *user_config_dir;
1870
1871   G_LOCK (g_utils_global);
1872
1873   if (g_user_config_dir == NULL)
1874     g_user_config_dir = g_build_user_config_dir ();
1875   user_config_dir = g_user_config_dir;
1876
1877   G_UNLOCK (g_utils_global);
1878
1879   return user_config_dir;
1880 }
1881
1882 static gchar *
1883 g_build_user_cache_dir (void)
1884 {
1885   gchar *cache_dir = NULL;
1886   const gchar *cache_dir_env = g_getenv ("XDG_CACHE_HOME");
1887
1888   if (cache_dir_env && cache_dir_env[0])
1889     cache_dir = g_strdup (cache_dir_env);
1890 #ifdef G_OS_WIN32
1891   else
1892     cache_dir = get_special_folder (&FOLDERID_InternetCache);
1893 #endif
1894   if (!cache_dir || !cache_dir[0])
1895     {
1896       gchar *home_dir = g_build_home_dir ();
1897       cache_dir = g_build_filename (home_dir, ".cache", NULL);
1898       g_free (home_dir);
1899     }
1900
1901   return g_steal_pointer (&cache_dir);
1902 }
1903
1904 /**
1905  * g_get_user_cache_dir:
1906  * 
1907  * Returns a base directory in which to store non-essential, cached
1908  * data specific to particular user.
1909  *
1910  * On UNIX platforms this is determined using the mechanisms described
1911  * in the
1912  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1913  * In this case the directory retrieved will be `XDG_CACHE_HOME`.
1914  *
1915  * On Windows it follows XDG Base Directory Specification if `XDG_CACHE_HOME` is defined.
1916  * If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
1917  * repository for temporary Internet files is used instead. A typical path is
1918  * `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
1919  * See the [documentation for `FOLDERID_InternetCache`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
1920  *
1921  * The return value is cached and modifying it at runtime is not supported, as
1922  * it’s not thread-safe to modify environment variables at runtime.
1923  *
1924  * Returns: (type filename) (transfer none): a string owned by GLib that
1925  *   must not be modified or freed.
1926  * Since: 2.6
1927  **/
1928 const gchar *
1929 g_get_user_cache_dir (void)
1930 {
1931   const gchar *user_cache_dir;
1932
1933   G_LOCK (g_utils_global);
1934
1935   if (g_user_cache_dir == NULL)
1936     g_user_cache_dir = g_build_user_cache_dir ();
1937   user_cache_dir = g_user_cache_dir;
1938
1939   G_UNLOCK (g_utils_global);
1940
1941   return user_cache_dir;
1942 }
1943
1944 static gchar *
1945 g_build_user_state_dir (void)
1946 {
1947   gchar *state_dir = NULL;
1948   const gchar *state_dir_env = g_getenv ("XDG_STATE_HOME");
1949
1950   if (state_dir_env && state_dir_env[0])
1951     state_dir = g_strdup (state_dir_env);
1952 #ifdef G_OS_WIN32
1953   else
1954     state_dir = get_special_folder (&FOLDERID_LocalAppData);
1955 #endif
1956   if (!state_dir || !state_dir[0])
1957     {
1958       gchar *home_dir = g_build_home_dir ();
1959       state_dir = g_build_filename (home_dir, ".local/state", NULL);
1960       g_free (home_dir);
1961     }
1962
1963   return g_steal_pointer (&state_dir);
1964 }
1965
1966 /**
1967  * g_get_user_state_dir:
1968  *
1969  * Returns a base directory in which to store state files specific to
1970  * particular user.
1971  *
1972  * On UNIX platforms this is determined using the mechanisms described
1973  * in the
1974  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1975  * In this case the directory retrieved will be `XDG_STATE_HOME`.
1976  *
1977  * On Windows it follows XDG Base Directory Specification if `XDG_STATE_HOME` is defined.
1978  * If `XDG_STATE_HOME` is undefined, the folder to use for local (as opposed
1979  * to roaming) application data is used instead. See the
1980  * [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
1981  * Note that in this case on Windows it will be the same
1982  * as what g_get_user_data_dir() returns.
1983  *
1984  * The return value is cached and modifying it at runtime is not supported, as
1985  * it’s not thread-safe to modify environment variables at runtime.
1986  *
1987  * Returns: (type filename) (transfer none): a string owned by GLib that
1988  *   must not be modified or freed.
1989  *
1990  * Since: 2.72
1991  **/
1992 const gchar *
1993 g_get_user_state_dir (void)
1994 {
1995   const gchar *user_state_dir;
1996
1997   G_LOCK (g_utils_global);
1998
1999   if (g_user_state_dir == NULL)
2000     g_user_state_dir = g_build_user_state_dir ();
2001   user_state_dir = g_user_state_dir;
2002
2003   G_UNLOCK (g_utils_global);
2004
2005   return user_state_dir;
2006 }
2007
2008 static gchar *
2009 g_build_user_runtime_dir (void)
2010 {
2011   gchar *runtime_dir = NULL;
2012   const gchar *runtime_dir_env = g_getenv ("XDG_RUNTIME_DIR");
2013
2014   if (runtime_dir_env && runtime_dir_env[0])
2015     {
2016       runtime_dir = g_strdup (runtime_dir_env);
2017
2018       /* If the XDG_RUNTIME_DIR environment variable is set, we are being told by
2019        * the OS that this directory exists and is appropriately configured
2020        * already.
2021        */
2022     }
2023   else
2024     {
2025       runtime_dir = g_build_user_cache_dir ();
2026
2027       /* Fallback case: the directory may not yet exist.
2028        *
2029        * The user should be able to rely on the directory existing
2030        * when the function returns.  Probably it already does, but
2031        * let's make sure.  Just do mkdir() directly since it will be
2032        * no more expensive than a stat() in the case that the
2033        * directory already exists and is a lot easier.
2034        *
2035        * $XDG_CACHE_HOME is probably ~/.cache/ so as long as $HOME
2036        * exists this will work.  If the user changed $XDG_CACHE_HOME
2037        * then they can make sure that it exists...
2038        */
2039       (void) g_mkdir (runtime_dir, 0700);
2040     }
2041
2042   return g_steal_pointer (&runtime_dir);
2043 }
2044
2045 /**
2046  * g_get_user_runtime_dir:
2047  *
2048  * Returns a directory that is unique to the current user on the local
2049  * system.
2050  *
2051  * This is determined using the mechanisms described
2052  * in the 
2053  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
2054  * This is the directory
2055  * specified in the `XDG_RUNTIME_DIR` environment variable.
2056  * In the case that this variable is not set, we return the value of
2057  * g_get_user_cache_dir(), after verifying that it exists.
2058  *
2059  * The return value is cached and modifying it at runtime is not supported, as
2060  * it’s not thread-safe to modify environment variables at runtime.
2061  *
2062  * Returns: (type filename): a string owned by GLib that must not be
2063  *     modified or freed.
2064  *
2065  * Since: 2.28
2066  **/
2067 const gchar *
2068 g_get_user_runtime_dir (void)
2069 {
2070   const gchar *user_runtime_dir;
2071
2072   G_LOCK (g_utils_global);
2073
2074   if (g_user_runtime_dir == NULL)
2075     g_user_runtime_dir = g_build_user_runtime_dir ();
2076   user_runtime_dir = g_user_runtime_dir;
2077
2078   G_UNLOCK (g_utils_global);
2079
2080   return user_runtime_dir;
2081 }
2082
2083 #ifdef HAVE_COCOA
2084
2085 /* Implemented in gutils-macos.m */
2086 void load_user_special_dirs_macos (gchar **table);
2087
2088 static void
2089 load_user_special_dirs (void)
2090 {
2091   load_user_special_dirs_macos (g_user_special_dirs);
2092 }
2093
2094 #elif defined(G_OS_WIN32)
2095
2096 static void
2097 load_user_special_dirs (void)
2098 {
2099   g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (&FOLDERID_Desktop);
2100   g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (&FOLDERID_Documents);
2101
2102   g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Downloads);
2103   if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
2104     g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Desktop);
2105
2106   g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (&FOLDERID_Music);
2107   g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (&FOLDERID_Pictures);
2108
2109   g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_Public);
2110   if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
2111     g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_PublicDocuments);
2112
2113   g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (&FOLDERID_Templates);
2114   g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (&FOLDERID_Videos);
2115 }
2116
2117 #else /* default is unix */
2118
2119 /* adapted from xdg-user-dir-lookup.c
2120  *
2121  * Copyright (C) 2007 Red Hat Inc.
2122  *
2123  * Permission is hereby granted, free of charge, to any person
2124  * obtaining a copy of this software and associated documentation files
2125  * (the "Software"), to deal in the Software without restriction,
2126  * including without limitation the rights to use, copy, modify, merge,
2127  * publish, distribute, sublicense, and/or sell copies of the Software,
2128  * and to permit persons to whom the Software is furnished to do so,
2129  * subject to the following conditions: 
2130  *
2131  * The above copyright notice and this permission notice shall be
2132  * included in all copies or substantial portions of the Software. 
2133  *
2134  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2135  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2136  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2137  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2138  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2139  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2140  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2141  * SOFTWARE.
2142  */
2143 static void
2144 load_user_special_dirs (void)
2145 {
2146   gchar *config_dir = NULL;
2147   gchar *config_file;
2148   gchar *data;
2149   gchar **lines;
2150   gint n_lines, i;
2151   
2152   config_dir = g_build_user_config_dir ();
2153   config_file = g_build_filename (config_dir,
2154                                   "user-dirs.dirs",
2155                                   NULL);
2156   g_free (config_dir);
2157
2158   if (!g_file_get_contents (config_file, &data, NULL, NULL))
2159     {
2160       g_free (config_file);
2161       return;
2162     }
2163
2164   lines = g_strsplit (data, "\n", -1);
2165   n_lines = g_strv_length (lines);
2166   g_free (data);
2167   
2168   for (i = 0; i < n_lines; i++)
2169     {
2170       gchar *buffer = lines[i];
2171       gchar *d, *p;
2172       gint len;
2173       gboolean is_relative = FALSE;
2174       GUserDirectory directory;
2175
2176       /* Remove newline at end */
2177       len = strlen (buffer);
2178       if (len > 0 && buffer[len - 1] == '\n')
2179         buffer[len - 1] = 0;
2180       
2181       p = buffer;
2182       while (*p == ' ' || *p == '\t')
2183         p++;
2184       
2185       if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0)
2186         {
2187           directory = G_USER_DIRECTORY_DESKTOP;
2188           p += strlen ("XDG_DESKTOP_DIR");
2189         }
2190       else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0)
2191         {
2192           directory = G_USER_DIRECTORY_DOCUMENTS;
2193           p += strlen ("XDG_DOCUMENTS_DIR");
2194         }
2195       else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0)
2196         {
2197           directory = G_USER_DIRECTORY_DOWNLOAD;
2198           p += strlen ("XDG_DOWNLOAD_DIR");
2199         }
2200       else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0)
2201         {
2202           directory = G_USER_DIRECTORY_MUSIC;
2203           p += strlen ("XDG_MUSIC_DIR");
2204         }
2205       else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0)
2206         {
2207           directory = G_USER_DIRECTORY_PICTURES;
2208           p += strlen ("XDG_PICTURES_DIR");
2209         }
2210       else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0)
2211         {
2212           directory = G_USER_DIRECTORY_PUBLIC_SHARE;
2213           p += strlen ("XDG_PUBLICSHARE_DIR");
2214         }
2215       else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0)
2216         {
2217           directory = G_USER_DIRECTORY_TEMPLATES;
2218           p += strlen ("XDG_TEMPLATES_DIR");
2219         }
2220       else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0)
2221         {
2222           directory = G_USER_DIRECTORY_VIDEOS;
2223           p += strlen ("XDG_VIDEOS_DIR");
2224         }
2225       else
2226         continue;
2227
2228       while (*p == ' ' || *p == '\t')
2229         p++;
2230
2231       if (*p != '=')
2232         continue;
2233       p++;
2234
2235       while (*p == ' ' || *p == '\t')
2236         p++;
2237
2238       if (*p != '"')
2239         continue;
2240       p++;
2241
2242       if (strncmp (p, "$HOME", 5) == 0)
2243         {
2244           p += 5;
2245           is_relative = TRUE;
2246         }
2247       else if (*p != '/')
2248         continue;
2249
2250       d = strrchr (p, '"');
2251       if (!d)
2252         continue;
2253       *d = 0;
2254
2255       d = p;
2256       
2257       /* remove trailing slashes */
2258       len = strlen (d);
2259       if (d[len - 1] == '/')
2260         d[len - 1] = 0;
2261       
2262       if (is_relative)
2263         {
2264           gchar *home_dir = g_build_home_dir ();
2265           g_user_special_dirs[directory] = g_build_filename (home_dir, d, NULL);
2266           g_free (home_dir);
2267         }
2268       else
2269         g_user_special_dirs[directory] = g_strdup (d);
2270     }
2271
2272   g_strfreev (lines);
2273   g_free (config_file);
2274 }
2275
2276 #endif /* platform-specific load_user_special_dirs implementations */
2277
2278
2279 /**
2280  * g_reload_user_special_dirs_cache:
2281  *
2282  * Resets the cache used for g_get_user_special_dir(), so
2283  * that the latest on-disk version is used. Call this only
2284  * if you just changed the data on disk yourself.
2285  *
2286  * Due to thread safety issues this may cause leaking of strings
2287  * that were previously returned from g_get_user_special_dir()
2288  * that can't be freed. We ensure to only leak the data for
2289  * the directories that actually changed value though.
2290  *
2291  * Since: 2.22
2292  */
2293 void
2294 g_reload_user_special_dirs_cache (void)
2295 {
2296   int i;
2297
2298   G_LOCK (g_utils_global);
2299
2300   if (g_user_special_dirs != NULL)
2301     {
2302       /* save a copy of the pointer, to check if some memory can be preserved */
2303       char **old_g_user_special_dirs = g_user_special_dirs;
2304       char *old_val;
2305
2306       /* recreate and reload our cache */
2307       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2308       load_user_special_dirs ();
2309
2310       /* only leak changed directories */
2311       for (i = 0; i < G_USER_N_DIRECTORIES; i++)
2312         {
2313           old_val = old_g_user_special_dirs[i];
2314           if (g_user_special_dirs[i] == NULL)
2315             {
2316               g_user_special_dirs[i] = old_val;
2317             }
2318           else if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0)
2319             {
2320               /* don't leak */
2321               g_free (g_user_special_dirs[i]);
2322               g_user_special_dirs[i] = old_val;
2323             }
2324           else
2325             g_free (old_val);
2326         }
2327
2328       /* free the old array */
2329       g_free (old_g_user_special_dirs);
2330     }
2331
2332   G_UNLOCK (g_utils_global);
2333 }
2334
2335 /**
2336  * g_get_user_special_dir:
2337  * @directory: the logical id of special directory
2338  *
2339  * Returns the full path of a special directory using its logical id.
2340  *
2341  * On UNIX this is done using the XDG special user directories.
2342  * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP
2343  * falls back to `$HOME/Desktop` when XDG special user directories have
2344  * not been set up. 
2345  *
2346  * Depending on the platform, the user might be able to change the path
2347  * of the special directory without requiring the session to restart; GLib
2348  * will not reflect any change once the special directories are loaded.
2349  *
2350  * Returns: (type filename) (nullable): the path to the specified special
2351  *   directory, or %NULL if the logical id was not found. The returned string is
2352  *   owned by GLib and should not be modified or freed.
2353  *
2354  * Since: 2.14
2355  */
2356 const gchar *
2357 g_get_user_special_dir (GUserDirectory directory)
2358 {
2359   const gchar *user_special_dir;
2360
2361   g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP &&
2362                         directory < G_USER_N_DIRECTORIES, NULL);
2363
2364   G_LOCK (g_utils_global);
2365
2366   if (G_UNLIKELY (g_user_special_dirs == NULL))
2367     {
2368       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2369
2370       load_user_special_dirs ();
2371
2372       /* Special-case desktop for historical compatibility */
2373       if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL)
2374         {
2375           gchar *home_dir = g_build_home_dir ();
2376           g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = g_build_filename (home_dir, "Desktop", NULL);
2377           g_free (home_dir);
2378         }
2379     }
2380   user_special_dir = g_user_special_dirs[directory];
2381
2382   G_UNLOCK (g_utils_global);
2383
2384   return user_special_dir;
2385 }
2386
2387 #ifdef G_OS_WIN32
2388
2389 #undef g_get_system_data_dirs
2390
2391 static HMODULE
2392 get_module_for_address (gconstpointer address)
2393 {
2394   /* Holds the g_utils_global lock */
2395
2396   HMODULE hmodule = NULL;
2397
2398   if (!address)
2399     return NULL;
2400
2401   if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
2402                            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
2403                            address, &hmodule))
2404     {
2405       MEMORY_BASIC_INFORMATION mbi;
2406       VirtualQuery (address, &mbi, sizeof (mbi));
2407       hmodule = (HMODULE) mbi.AllocationBase;
2408     }
2409
2410   return hmodule;
2411 }
2412
2413 static gchar *
2414 get_module_share_dir (gconstpointer address)
2415 {
2416   HMODULE hmodule;
2417   gchar *filename;
2418   gchar *retval;
2419
2420   hmodule = get_module_for_address (address);
2421   if (hmodule == NULL)
2422     return NULL;
2423
2424   filename = g_win32_get_package_installation_directory_of_module (hmodule);
2425   retval = g_build_filename (filename, "share", NULL);
2426   g_free (filename);
2427
2428   return retval;
2429 }
2430
2431 static const gchar * const *
2432 g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
2433 {
2434   GArray *data_dirs;
2435   HMODULE hmodule;
2436   static GHashTable *per_module_data_dirs = NULL;
2437   gchar **retval;
2438   gchar *p;
2439   gchar *exe_root;
2440
2441   hmodule = NULL;
2442   if (address_of_function)
2443     {
2444       G_LOCK (g_utils_global);
2445       hmodule = get_module_for_address (address_of_function);
2446       if (hmodule != NULL)
2447         {
2448           if (per_module_data_dirs == NULL)
2449             per_module_data_dirs = g_hash_table_new (NULL, NULL);
2450           else
2451             {
2452               retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
2453               
2454               if (retval != NULL)
2455                 {
2456                   G_UNLOCK (g_utils_global);
2457                   return (const gchar * const *) retval;
2458                 }
2459             }
2460         }
2461     }
2462
2463   data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
2464
2465   /* Documents and Settings\All Users\Application Data */
2466   p = get_special_folder (&FOLDERID_ProgramData);
2467   if (p)
2468     g_array_append_val (data_dirs, p);
2469   
2470   /* Documents and Settings\All Users\Documents */
2471   p = get_special_folder (&FOLDERID_PublicDocuments);
2472   if (p)
2473     g_array_append_val (data_dirs, p);
2474         
2475   /* Using the above subfolders of Documents and Settings perhaps
2476    * makes sense from a Windows perspective.
2477    *
2478    * But looking at the actual use cases of this function in GTK+
2479    * and GNOME software, what we really want is the "share"
2480    * subdirectory of the installation directory for the package
2481    * our caller is a part of.
2482    *
2483    * The address_of_function parameter, if non-NULL, points to a
2484    * function in the calling module. Use that to determine that
2485    * module's installation folder, and use its "share" subfolder.
2486    *
2487    * Additionally, also use the "share" subfolder of the installation
2488    * locations of GLib and the .exe file being run.
2489    *
2490    * To guard against none of the above being what is really wanted,
2491    * callers of this function should have Win32-specific code to look
2492    * up their installation folder themselves, and handle a subfolder
2493    * "share" of it in the same way as the folders returned from this
2494    * function.
2495    */
2496
2497   p = get_module_share_dir (address_of_function);
2498   if (p)
2499     g_array_append_val (data_dirs, p);
2500     
2501   if (glib_dll != NULL)
2502     {
2503       gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll);
2504       p = g_build_filename (glib_root, "share", NULL);
2505       if (p)
2506         g_array_append_val (data_dirs, p);
2507       g_free (glib_root);
2508     }
2509   
2510   exe_root = g_win32_get_package_installation_directory_of_module (NULL);
2511   p = g_build_filename (exe_root, "share", NULL);
2512   if (p)
2513     g_array_append_val (data_dirs, p);
2514   g_free (exe_root);
2515
2516   retval = (gchar **) g_array_free (data_dirs, FALSE);
2517
2518   if (address_of_function)
2519     {
2520       if (hmodule != NULL)
2521         g_hash_table_insert (per_module_data_dirs, hmodule, retval);
2522       G_UNLOCK (g_utils_global);
2523     }
2524
2525   return (const gchar * const *) retval;
2526 }
2527
2528 const gchar * const *
2529 g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void))
2530 {
2531   gboolean should_call_g_get_system_data_dirs;
2532
2533   should_call_g_get_system_data_dirs = TRUE;
2534   /* These checks are the same as the ones that g_build_system_data_dirs() does.
2535    * Please keep them in sync.
2536    */
2537   G_LOCK (g_utils_global);
2538
2539   if (!g_system_data_dirs)
2540     {
2541       const gchar *data_dirs = g_getenv ("XDG_DATA_DIRS");
2542
2543       if (!data_dirs || !data_dirs[0])
2544         should_call_g_get_system_data_dirs = FALSE;
2545     }
2546
2547   G_UNLOCK (g_utils_global);
2548
2549   /* There is a subtle difference between g_win32_get_system_data_dirs_for_module (NULL),
2550    * which is what GLib code can normally call,
2551    * and g_win32_get_system_data_dirs_for_module (&_g_win32_get_system_data_dirs),
2552    * which is what the inline function used by non-GLib code calls.
2553    * The former gets prefix relative to currently-running executable,
2554    * the latter - relative to the module that calls _g_win32_get_system_data_dirs()
2555    * (disguised as g_get_system_data_dirs()), which could be an executable or
2556    * a DLL that is located somewhere else.
2557    * This is why that inline function in gutils.h exists, and why we can't just
2558    * call g_get_system_data_dirs() from there - because we need to get the address
2559    * local to the non-GLib caller-module.
2560    */
2561
2562   /*
2563    * g_get_system_data_dirs() will fall back to calling
2564    * g_win32_get_system_data_dirs_for_module_real(NULL) if XDG_DATA_DIRS is NULL
2565    * or an empty string. The checks above ensure that we do not call it in such
2566    * cases and use the address_of_function that we've been given by the inline function.
2567    * The reason we're calling g_get_system_data_dirs /at all/ is to give
2568    * XDG_DATA_DIRS precedence (if it is set).
2569    */
2570   if (should_call_g_get_system_data_dirs)
2571     return g_get_system_data_dirs ();
2572
2573   return g_win32_get_system_data_dirs_for_module_real (address_of_function);
2574 }
2575
2576 #endif
2577
2578 static gchar **
2579 g_build_system_data_dirs (void)
2580 {
2581   gchar **data_dir_vector = NULL;
2582   gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2583
2584   /* These checks are the same as the ones that g_win32_get_system_data_dirs_for_module()
2585    * does. Please keep them in sync.
2586    */
2587 #ifndef G_OS_WIN32
2588   if (!data_dirs || !data_dirs[0])
2589     data_dirs = "/usr/local/share/:/usr/share/";
2590
2591   data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2592 #else
2593   if (!data_dirs || !data_dirs[0])
2594     data_dir_vector = g_strdupv ((gchar **) g_win32_get_system_data_dirs_for_module_real (NULL));
2595   else
2596     data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2597 #endif
2598
2599   return g_steal_pointer (&data_dir_vector);
2600 }
2601
2602 /**
2603  * g_get_system_data_dirs:
2604  * 
2605  * Returns an ordered list of base directories in which to access 
2606  * system-wide application data.
2607  *
2608  * On UNIX platforms this is determined using the mechanisms described
2609  * in the
2610  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec)
2611  * In this case the list of directories retrieved will be `XDG_DATA_DIRS`.
2612  *
2613  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_DIRS` is defined.
2614  * If `XDG_DATA_DIRS` is undefined,
2615  * the first elements in the list are the Application Data
2616  * and Documents folders for All Users. (These can be determined only
2617  * on Windows 2000 or later and are not present in the list on other
2618  * Windows versions.) See documentation for FOLDERID_ProgramData and
2619  * FOLDERID_PublicDocuments.
2620  *
2621  * Then follows the "share" subfolder in the installation folder for
2622  * the package containing the DLL that calls this function, if it can
2623  * be determined.
2624  * 
2625  * Finally the list contains the "share" subfolder in the installation
2626  * folder for GLib, and in the installation folder for the package the
2627  * application's .exe file belongs to.
2628  *
2629  * The installation folders above are determined by looking up the
2630  * folder where the module (DLL or EXE) in question is located. If the
2631  * folder's name is "bin", its parent is used, otherwise the folder
2632  * itself.
2633  *
2634  * Note that on Windows the returned list can vary depending on where
2635  * this function is called.
2636  *
2637  * The return value is cached and modifying it at runtime is not supported, as
2638  * it’s not thread-safe to modify environment variables at runtime.
2639  *
2640  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2641  *     a %NULL-terminated array of strings owned by GLib that must not be
2642  *     modified or freed.
2643  * 
2644  * Since: 2.6
2645  **/
2646 const gchar * const * 
2647 g_get_system_data_dirs (void)
2648 {
2649   const gchar * const *system_data_dirs;
2650
2651   G_LOCK (g_utils_global);
2652
2653   if (g_system_data_dirs == NULL)
2654     g_system_data_dirs = g_build_system_data_dirs ();
2655   system_data_dirs = (const gchar * const *) g_system_data_dirs;
2656
2657   G_UNLOCK (g_utils_global);
2658
2659   return system_data_dirs;
2660 }
2661
2662 static gchar **
2663 g_build_system_config_dirs (void)
2664 {
2665   gchar **conf_dir_vector = NULL;
2666   const gchar *conf_dirs = g_getenv ("XDG_CONFIG_DIRS");
2667 #ifdef G_OS_WIN32
2668   if (conf_dirs)
2669     {
2670       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2671     }
2672   else
2673     {
2674       gchar *special_conf_dirs = get_special_folder (&FOLDERID_ProgramData);
2675
2676       if (special_conf_dirs)
2677         conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2678       else
2679         /* Return empty list */
2680         conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2681
2682       g_free (special_conf_dirs);
2683     }
2684 #else
2685   if (!conf_dirs || !conf_dirs[0])
2686     conf_dirs = "/etc/xdg";
2687
2688   conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2689 #endif
2690
2691   return g_steal_pointer (&conf_dir_vector);
2692 }
2693
2694 /**
2695  * g_get_system_config_dirs:
2696  * 
2697  * Returns an ordered list of base directories in which to access 
2698  * system-wide configuration information.
2699  *
2700  * On UNIX platforms this is determined using the mechanisms described
2701  * in the
2702  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
2703  * In this case the list of directories retrieved will be `XDG_CONFIG_DIRS`.
2704  *
2705  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_DIRS` is defined.
2706  * If `XDG_CONFIG_DIRS` is undefined, the directory that contains application
2707  * data for all users is used instead. A typical path is
2708  * `C:\Documents and Settings\All Users\Application Data`.
2709  * This folder is used for application data
2710  * that is not user specific. For example, an application can store
2711  * a spell-check dictionary, a database of clip art, or a log file in the
2712  * FOLDERID_ProgramData folder. This information will not roam and is available
2713  * to anyone using the computer.
2714  *
2715  * The return value is cached and modifying it at runtime is not supported, as
2716  * it’s not thread-safe to modify environment variables at runtime.
2717  *
2718  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2719  *     a %NULL-terminated array of strings owned by GLib that must not be
2720  *     modified or freed.
2721  * 
2722  * Since: 2.6
2723  **/
2724 const gchar * const *
2725 g_get_system_config_dirs (void)
2726 {
2727   const gchar * const *system_config_dirs;
2728
2729   G_LOCK (g_utils_global);
2730
2731   if (g_system_config_dirs == NULL)
2732     g_system_config_dirs = g_build_system_config_dirs ();
2733   system_config_dirs = (const gchar * const *) g_system_config_dirs;
2734
2735   G_UNLOCK (g_utils_global);
2736
2737   return system_config_dirs;
2738 }
2739
2740 /**
2741  * g_nullify_pointer:
2742  * @nullify_location: (not nullable): the memory address of the pointer.
2743  *
2744  * Set the pointer at the specified location to %NULL.
2745  **/
2746 void
2747 g_nullify_pointer (gpointer *nullify_location)
2748 {
2749   g_return_if_fail (nullify_location != NULL);
2750
2751   *nullify_location = NULL;
2752 }
2753
2754 #define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000))
2755 #define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
2756 #define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
2757 #define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
2758 #define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
2759 #define EXABYTE_FACTOR  (PETABYTE_FACTOR * KILOBYTE_FACTOR)
2760
2761 #define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
2762 #define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2763 #define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2764 #define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2765 #define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2766 #define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2767
2768 /**
2769  * g_format_size:
2770  * @size: a size in bytes
2771  *
2772  * Formats a size (for example the size of a file) into a human readable
2773  * string.  Sizes are rounded to the nearest size prefix (kB, MB, GB)
2774  * and are displayed rounded to the nearest tenth. E.g. the file size
2775  * 3292528 bytes will be converted into the string "3.2 MB". The returned string
2776  * is UTF-8, and may use a non-breaking space to separate the number and units,
2777  * to ensure they aren’t separated when line wrapped.
2778  *
2779  * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes).
2780  *
2781  * This string should be freed with g_free() when not needed any longer.
2782  *
2783  * See g_format_size_full() for more options about how the size might be
2784  * formatted.
2785  *
2786  * Returns: (transfer full): a newly-allocated formatted string containing
2787  *   a human readable file size
2788  *
2789  * Since: 2.30
2790  */
2791 gchar *
2792 g_format_size (guint64 size)
2793 {
2794   return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT);
2795 }
2796
2797 /**
2798  * GFormatSizeFlags:
2799  * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size()
2800  * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part
2801  *     of the returned string.  For example, "45.6 kB (45,612 bytes)".
2802  * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style
2803  *     suffixes. IEC units should only be used for reporting things with
2804  *     a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
2805  *     Network and storage sizes should be reported in the normal SI units.
2806  * @G_FORMAT_SIZE_BITS: set the size as a quantity in bits, rather than
2807  *     bytes, and return units in bits. For example, â€˜Mb’ rather than â€˜MB’.
2808  * @G_FORMAT_SIZE_ONLY_VALUE: return only value, without unit; this should
2809  *     not be used together with @G_FORMAT_SIZE_LONG_FORMAT
2810  *     nor @G_FORMAT_SIZE_ONLY_UNIT. Since: 2.74
2811  * @G_FORMAT_SIZE_ONLY_UNIT: return only unit, without value; this should
2812  *     not be used together with @G_FORMAT_SIZE_LONG_FORMAT
2813  *     nor @G_FORMAT_SIZE_ONLY_VALUE. Since: 2.74
2814  *
2815  * Flags to modify the format of the string returned by g_format_size_full().
2816  */
2817
2818 #pragma GCC diagnostic push
2819 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2820
2821 /**
2822  * g_format_size_full:
2823  * @size: a size in bytes
2824  * @flags: #GFormatSizeFlags to modify the output
2825  *
2826  * Formats a size.
2827  *
2828  * This function is similar to g_format_size() but allows for flags
2829  * that modify the output. See #GFormatSizeFlags.
2830  *
2831  * Returns: (transfer full): a newly-allocated formatted string
2832  *   containing a human readable file size
2833  *
2834  * Since: 2.30
2835  */
2836 gchar *
2837 g_format_size_full (guint64          size,
2838                     GFormatSizeFlags flags)
2839 {
2840   struct Format
2841   {
2842     guint64 factor;
2843     char string[10];
2844   };
2845
2846   typedef enum
2847   {
2848     FORMAT_BYTES,
2849     FORMAT_BYTES_IEC,
2850     FORMAT_BITS,
2851     FORMAT_BITS_IEC
2852   } FormatIndex;
2853
2854   const struct Format formats[4][6] = {
2855     {
2856       /* Translators: A unit symbol for size formatting, showing for example: "13.0 kB" */
2857       { KILOBYTE_FACTOR, N_("kB") },
2858       /* Translators: A unit symbol for size formatting, showing for example: "13.0 MB" */
2859       { MEGABYTE_FACTOR, N_("MB") },
2860       /* Translators: A unit symbol for size formatting, showing for example: "13.0 GB" */
2861       { GIGABYTE_FACTOR, N_("GB") },
2862       /* Translators: A unit symbol for size formatting, showing for example: "13.0 TB" */
2863       { TERABYTE_FACTOR, N_("TB") },
2864       /* Translators: A unit symbol for size formatting, showing for example: "13.0 PB" */
2865       { PETABYTE_FACTOR, N_("PB") },
2866       /* Translators: A unit symbol for size formatting, showing for example: "13.0 EB" */
2867       { EXABYTE_FACTOR,  N_("EB") }
2868     },
2869     {
2870       /* Translators: A unit symbol for size formatting, showing for example: "13.0 KiB" */
2871       { KIBIBYTE_FACTOR, N_("KiB") },
2872       /* Translators: A unit symbol for size formatting, showing for example: "13.0 MiB" */
2873       { MEBIBYTE_FACTOR, N_("MiB") },
2874       /* Translators: A unit symbol for size formatting, showing for example: "13.0 GiB" */
2875       { GIBIBYTE_FACTOR, N_("GiB") },
2876       /* Translators: A unit symbol for size formatting, showing for example: "13.0 TiB" */
2877       { TEBIBYTE_FACTOR, N_("TiB") },
2878       /* Translators: A unit symbol for size formatting, showing for example: "13.0 PiB" */
2879       { PEBIBYTE_FACTOR, N_("PiB") },
2880       /* Translators: A unit symbol for size formatting, showing for example: "13.0 EiB" */
2881       { EXBIBYTE_FACTOR, N_("EiB") }
2882     },
2883     {
2884       /* Translators: A unit symbol for size formatting, showing for example: "13.0 kb" */
2885       { KILOBYTE_FACTOR, N_("kb") },
2886       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Mb" */
2887       { MEGABYTE_FACTOR, N_("Mb") },
2888       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Gb" */
2889       { GIGABYTE_FACTOR, N_("Gb") },
2890       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Tb" */
2891       { TERABYTE_FACTOR, N_("Tb") },
2892       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Pb" */
2893       { PETABYTE_FACTOR, N_("Pb") },
2894       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Eb" */
2895       { EXABYTE_FACTOR,  N_("Eb") }
2896     },
2897     {
2898       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Kib" */
2899       { KIBIBYTE_FACTOR, N_("Kib") },
2900       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Mib" */
2901       { MEBIBYTE_FACTOR, N_("Mib") },
2902       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Gib" */
2903       { GIBIBYTE_FACTOR, N_("Gib") },
2904       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Tib" */
2905       { TEBIBYTE_FACTOR, N_("Tib") },
2906       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Pib" */
2907       { PEBIBYTE_FACTOR, N_("Pib") },
2908       /* Translators: A unit symbol for size formatting, showing for example: "13.0 Eib" */
2909       { EXBIBYTE_FACTOR, N_("Eib") }
2910     }
2911   };
2912
2913   GString *string;
2914   FormatIndex index;
2915
2916   g_return_val_if_fail ((flags & (G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_ONLY_VALUE)) != (G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_ONLY_VALUE), NULL);
2917   g_return_val_if_fail ((flags & (G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_ONLY_UNIT)) != (G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_ONLY_UNIT), NULL);
2918   g_return_val_if_fail ((flags & (G_FORMAT_SIZE_ONLY_VALUE | G_FORMAT_SIZE_ONLY_UNIT)) != (G_FORMAT_SIZE_ONLY_VALUE | G_FORMAT_SIZE_ONLY_UNIT), NULL);
2919
2920   string = g_string_new (NULL);
2921
2922   switch (flags & ~(G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_ONLY_VALUE | G_FORMAT_SIZE_ONLY_UNIT))
2923     {
2924     case G_FORMAT_SIZE_DEFAULT:
2925       index = FORMAT_BYTES;
2926       break;
2927     case (G_FORMAT_SIZE_DEFAULT | G_FORMAT_SIZE_IEC_UNITS):
2928       index = FORMAT_BYTES_IEC;
2929       break;
2930     case G_FORMAT_SIZE_BITS:
2931       index = FORMAT_BITS;
2932       break;
2933     case (G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS):
2934       index = FORMAT_BITS_IEC;
2935       break;
2936     default:
2937       g_assert_not_reached ();
2938     }
2939
2940
2941   if (size < formats[index][0].factor)
2942     {
2943       const char * units;
2944
2945       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
2946         {
2947           units = g_dngettext (GETTEXT_PACKAGE, "byte", "bytes", (guint) size);
2948         }
2949       else
2950         {
2951           units = g_dngettext (GETTEXT_PACKAGE, "bit", "bits", (guint) size);
2952         }
2953
2954       if ((flags & G_FORMAT_SIZE_ONLY_UNIT) != 0)
2955         g_string_append (string, units);
2956       else if ((flags & G_FORMAT_SIZE_ONLY_VALUE) != 0)
2957         /* Translators: The "%u" is replaced with the size value, like "13"; it could
2958          * be part of "13 bytes", but only the number is requested this time. */
2959         g_string_printf (string, C_("format-size", "%u"), (guint) size);
2960       else
2961         {
2962           /* Translators: The first "%u" is replaced with the value, the "%s" with a unit of the value.
2963            * The order can be changed with "%$2s %$1u". An example: "13 bytes" */
2964           g_string_printf (string, C_("format-size", "%u %s"), (guint) size, units);
2965         }
2966
2967       flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
2968     }
2969   else
2970     {
2971       const gsize n = G_N_ELEMENTS (formats[index]);
2972       const gchar * units;
2973       gdouble value;
2974       gsize i;
2975
2976       /*
2977        * Point the last format (the highest unit) by default
2978        * and then then scan all formats, starting with the 2nd one
2979        * because the 1st is already managed by with the plural form
2980        */
2981       const struct Format * f = &formats[index][n - 1];
2982
2983       for (i = 1; i < n; i++)
2984         {
2985           if (size < formats[index][i].factor)
2986             {
2987               f = &formats[index][i - 1];
2988               break;
2989             }
2990         }
2991
2992       units = _(f->string);
2993       value = (gdouble) size / (gdouble) f->factor;
2994
2995       if ((flags & G_FORMAT_SIZE_ONLY_UNIT) != 0)
2996         g_string_append (string, units);
2997       else if ((flags & G_FORMAT_SIZE_ONLY_VALUE) != 0)
2998         /* Translators: The "%.1f" is replaced with the size value, like "13.0"; it could
2999          * be part of "13.0 MB", but only the number is requested this time. */
3000         g_string_printf (string, C_("format-size", "%.1f"), value);
3001       else
3002         {
3003           /* Translators: The first "%.1f" is replaced with the value, the "%s" with a unit of the value.
3004            * The order can be changed with "%$2s %$1.1f". Keep the no-break space between the value and
3005            * the unit symbol. An example: "13.0 MB" */
3006           g_string_printf (string, C_("format-size", "%.1f %s"), value, units);
3007         }
3008     }
3009
3010   if (flags & G_FORMAT_SIZE_LONG_FORMAT)
3011     {
3012       /* First problem: we need to use the number of bytes to decide on
3013        * the plural form that is used for display, but the number of
3014        * bytes potentially exceeds the size of a guint (which is what
3015        * ngettext() takes).
3016        *
3017        * From a pragmatic standpoint, it seems that all known languages
3018        * base plural forms on one or both of the following:
3019        *
3020        *   - the lowest digits of the number
3021        *
3022        *   - if the number if greater than some small value
3023        *
3024        * Here's how we fake it:  Draw an arbitrary line at one thousand.
3025        * If the number is below that, then fine.  If it is above it,
3026        * then we take the modulus of the number by one thousand (in
3027        * order to keep the lowest digits) and add one thousand to that
3028        * (in order to ensure that 1001 is not treated the same as 1).
3029        */
3030       guint plural_form = size < 1000 ? size : size % 1000 + 1000;
3031
3032       /* Second problem: we need to translate the string "%u byte/bit" and
3033        * "%u bytes/bits" for pluralisation, but the correct number format to
3034        * use for a gsize is different depending on which architecture
3035        * we're on.
3036        *
3037        * Solution: format the number separately and use "%s bytes/bits" on
3038        * all platforms.
3039        */
3040       const gchar *translated_format;
3041       gchar *formatted_number;
3042
3043       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
3044         {
3045           /* Translators: the %s in "%s bytes" will always be replaced by a number. */
3046           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
3047         }
3048       else
3049         {
3050           /* Translators: the %s in "%s bits" will always be replaced by a number. */
3051           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form);
3052         }
3053       formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size);
3054
3055       g_string_append (string, " (");
3056       g_string_append_printf (string, translated_format, formatted_number);
3057       g_free (formatted_number);
3058       g_string_append (string, ")");
3059     }
3060
3061   return g_string_free (string, FALSE);
3062 }
3063
3064 #pragma GCC diagnostic pop
3065
3066 /**
3067  * g_format_size_for_display:
3068  * @size: a size in bytes
3069  *
3070  * Formats a size (for example the size of a file) into a human
3071  * readable string. Sizes are rounded to the nearest size prefix
3072  * (KB, MB, GB) and are displayed rounded to the nearest tenth.
3073  * E.g. the file size 3292528 bytes will be converted into the
3074  * string "3.1 MB".
3075  *
3076  * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
3077  *
3078  * This string should be freed with g_free() when not needed any longer.
3079  *
3080  * Returns: (transfer full): a newly-allocated formatted string
3081  *   containing a human readable file size
3082  *
3083  * Since: 2.16
3084  *
3085  * Deprecated:2.30: This function is broken due to its use of SI
3086  *     suffixes to denote IEC units. Use g_format_size() instead.
3087  */
3088 gchar *
3089 g_format_size_for_display (goffset size)
3090 {
3091   if (size < (goffset) KIBIBYTE_FACTOR)
3092     return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
3093   else
3094     {
3095       gdouble displayed_size;
3096
3097       if (size < (goffset) MEBIBYTE_FACTOR)
3098         {
3099           displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
3100           /* Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to
3101            * mean 1024 bytes.  I am aware that 'KB' is not correct, but it has been preserved for reasons of
3102            * compatibility.  Users will not see this string unless a program is using this deprecated function.
3103            * Please translate as literally as possible.
3104            */
3105           return g_strdup_printf (_("%.1f KB"), displayed_size);
3106         }
3107       else if (size < (goffset) GIBIBYTE_FACTOR)
3108         {
3109           displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR;
3110           return g_strdup_printf (_("%.1f MB"), displayed_size);
3111         }
3112       else if (size < (goffset) TEBIBYTE_FACTOR)
3113         {
3114           displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR;
3115           return g_strdup_printf (_("%.1f GB"), displayed_size);
3116         }
3117       else if (size < (goffset) PEBIBYTE_FACTOR)
3118         {
3119           displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR;
3120           return g_strdup_printf (_("%.1f TB"), displayed_size);
3121         }
3122       else if (size < (goffset) EXBIBYTE_FACTOR)
3123         {
3124           displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR;
3125           return g_strdup_printf (_("%.1f PB"), displayed_size);
3126         }
3127       else
3128         {
3129           displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR;
3130           return g_strdup_printf (_("%.1f EB"), displayed_size);
3131         }
3132     }
3133 }
3134
3135 #if defined (G_OS_WIN32) && !defined (_WIN64)
3136
3137 /* Binary compatibility versions. Not for newly compiled code. */
3138
3139 _GLIB_EXTERN const gchar *g_get_user_name_utf8        (void);
3140 _GLIB_EXTERN const gchar *g_get_real_name_utf8        (void);
3141 _GLIB_EXTERN const gchar *g_get_home_dir_utf8         (void);
3142 _GLIB_EXTERN const gchar *g_get_tmp_dir_utf8          (void);
3143 _GLIB_EXTERN gchar       *g_find_program_in_path_utf8 (const gchar *program);
3144
3145 gchar *
3146 g_find_program_in_path_utf8 (const gchar *program)
3147 {
3148   return g_find_program_in_path (program);
3149 }
3150
3151 const gchar *g_get_user_name_utf8 (void) { return g_get_user_name (); }
3152 const gchar *g_get_real_name_utf8 (void) { return g_get_real_name (); }
3153 const gchar *g_get_home_dir_utf8 (void) { return g_get_home_dir (); }
3154 const gchar *g_get_tmp_dir_utf8 (void) { return g_get_tmp_dir (); }
3155
3156 #endif
3157
3158 /* Private API:
3159  *
3160  * Returns %TRUE if the current process was executed as setuid
3161  */ 
3162 gboolean
3163 g_check_setuid (void)
3164 {
3165 #if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) && defined(AT_SECURE)
3166   unsigned long value;
3167   int errsv;
3168
3169   errno = 0;
3170   value = getauxval (AT_SECURE);
3171   errsv = errno;
3172   if (errsv)
3173     g_error ("getauxval () failed: %s", g_strerror (errsv));
3174   return value;
3175 #elif defined(HAVE_ISSETUGID) && !defined(__BIONIC__)
3176   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
3177
3178   /* Android had it in older versions but the new 64 bit ABI does not
3179    * have it anymore, and some versions of the 32 bit ABI neither.
3180    * https://code.google.com/p/android-developer-preview/issues/detail?id=168
3181    */
3182   return issetugid ();
3183 #elif defined(G_OS_UNIX)
3184   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
3185   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
3186
3187   static gsize check_setuid_initialised;
3188   static gboolean is_setuid;
3189
3190   if (g_once_init_enter (&check_setuid_initialised))
3191     {
3192 #ifdef HAVE_GETRESUID
3193       /* These aren't in the header files, so we prototype them here.
3194        */
3195       int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
3196       int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
3197       
3198       if (getresuid (&ruid, &euid, &suid) != 0 ||
3199           getresgid (&rgid, &egid, &sgid) != 0)
3200 #endif /* HAVE_GETRESUID */
3201         {
3202           suid = ruid = getuid ();
3203           sgid = rgid = getgid ();
3204           euid = geteuid ();
3205           egid = getegid ();
3206         }
3207
3208       is_setuid = (ruid != euid || ruid != suid ||
3209                    rgid != egid || rgid != sgid);
3210
3211       g_once_init_leave (&check_setuid_initialised, 1);
3212     }
3213   return is_setuid;
3214 #else
3215   return FALSE;
3216 #endif
3217 }
3218
3219 #ifdef G_OS_WIN32
3220 /**
3221  * g_abort:
3222  *
3223  * A wrapper for the POSIX abort() function.
3224  *
3225  * On Windows it is a function that makes extra effort (including a call
3226  * to abort()) to ensure that a debugger-catchable exception is thrown
3227  * before the program terminates.
3228  *
3229  * See your C library manual for more details about abort().
3230  *
3231  * Since: 2.50
3232  */
3233 void
3234 g_abort (void)
3235 {
3236   /* One call to break the debugger
3237    * We check if a debugger is actually attached to
3238    * avoid a windows error reporting popup window
3239    * when run in a test harness / on CI
3240    */
3241   if (IsDebuggerPresent ())
3242     DebugBreak ();
3243   /* One call in case CRT changes its abort() behaviour */
3244   abort ();
3245   /* And one call to bind them all and terminate the program for sure */
3246   ExitProcess (127);
3247 }
3248 #endif