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