updated
[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 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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
29  */
30
31 #include "config.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <errno.h>
41 #ifdef HAVE_PWD_H
42 #include <pwd.h>
43 #endif
44 #include <sys/types.h>
45 #ifdef HAVE_SYS_PARAM_H
46 #include <sys/param.h>
47 #endif
48
49 /* implement gutils's inline functions
50  */
51 #define G_IMPLEMENT_INLINES 1
52 #define __G_UTILS_C__
53 #include "glib.h"
54 #include "gprintfint.h"
55
56 #ifdef  MAXPATHLEN
57 #define G_PATH_LENGTH   MAXPATHLEN
58 #elif   defined (PATH_MAX)
59 #define G_PATH_LENGTH   PATH_MAX
60 #elif   defined (_PC_PATH_MAX)
61 #define G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
62 #else   
63 #define G_PATH_LENGTH   2048
64 #endif
65
66 #ifdef G_PLATFORM_WIN32
67 #  define STRICT                /* Strict typing, please */
68 #  include <windows.h>
69 #  undef STRICT
70 #  include <lmcons.h>           /* For UNLEN */
71 #  include <ctype.h>
72 #endif /* G_PLATFORM_WIN32 */
73
74 #ifdef G_OS_WIN32
75 #  include <direct.h>
76 #endif
77
78 #ifdef HAVE_CODESET
79 #include <langinfo.h>
80 #endif
81
82 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
83 #include <libintl.h>
84 #endif
85
86 /* G_IS_DIR_SEPARATOR probably should be made public in GLib 2.4 */
87 #ifdef G_OS_WIN32
88 #define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR || c == '/')
89 #else
90 #define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR)
91 #endif
92
93 const guint glib_major_version = GLIB_MAJOR_VERSION;
94 const guint glib_minor_version = GLIB_MINOR_VERSION;
95 const guint glib_micro_version = GLIB_MICRO_VERSION;
96 const guint glib_interface_age = GLIB_INTERFACE_AGE;
97 const guint glib_binary_age = GLIB_BINARY_AGE;
98
99 /**
100  * glib_check_version:
101  * @required_major: the required major version.
102  * @required_minor: the required major version.
103  * @required_micro: the required major version.
104  *
105  * Checks that the GLib library in use is compatible with the
106  * given version. Generally you would pass in the constants
107  * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION
108  * as the three arguments to this function; that produces
109  * a check that the library in use is compatible with
110  * the version of GLib the application or module was compiled
111  * against.
112  *
113  * Compatibility is defined by two things: first the version
114  * of the running library is newer than the version
115  * @required_major.required_minor.@required_micro. Second
116  * the running library must be binary compatible with the
117  * version @required_major.required_minor.@required_micro
118  * (same major version.)
119  *
120  * Return value: %NULL if the GLib library is compatible with the
121  *   given version, or a string describing the version mismatch.
122  *   The returned string is owned by GLib and must not be modified
123  *   or freed.
124  *
125  * Since: 2.6
126  **/
127 const gchar *
128 glib_check_version (guint required_major,
129                     guint required_minor,
130                     guint required_micro)
131 {
132   gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION;
133   gint required_effective_micro = 100 * required_minor + required_micro;
134
135   if (required_major > GLIB_MAJOR_VERSION)
136     return "GLib version too old (major mismatch)";
137   if (required_major < GLIB_MAJOR_VERSION)
138     return "GLib version too new (major mismatch)";
139   if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE)
140     return "GLib version too new (micro mismatch)";
141   if (required_effective_micro > glib_effective_micro)
142     return "GLib version too old (micro mismatch)";
143   return NULL;
144 }
145
146 #if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
147 void 
148 g_memmove (gpointer dest, gconstpointer src, gulong len)
149 {
150   gchar* destptr = dest;
151   const gchar* srcptr = src;
152   if (src + len < dest || dest + len < src)
153     {
154       bcopy (src, dest, len);
155       return;
156     }
157   else if (dest <= src)
158     {
159       while (len--)
160         *(destptr++) = *(srcptr++);
161     }
162   else
163     {
164       destptr += len;
165       srcptr += len;
166       while (len--)
167         *(--destptr) = *(--srcptr);
168     }
169 }
170 #endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
171
172 void
173 g_atexit (GVoidFunc func)
174 {
175   gint result;
176   const gchar *error = NULL;
177
178   /* keep this in sync with glib.h */
179
180 #ifdef  G_NATIVE_ATEXIT
181   result = ATEXIT (func);
182   if (result)
183     error = g_strerror (errno);
184 #elif defined (HAVE_ATEXIT)
185 #  ifdef NeXT /* @#%@! NeXTStep */
186   result = !atexit ((void (*)(void)) func);
187   if (result)
188     error = g_strerror (errno);
189 #  else
190   result = atexit ((void (*)(void)) func);
191   if (result)
192     error = g_strerror (errno);
193 #  endif /* NeXT */
194 #elif defined (HAVE_ON_EXIT)
195   result = on_exit ((void (*)(int, void *)) func, NULL);
196   if (result)
197     error = g_strerror (errno);
198 #else
199   result = 0;
200   error = "no implementation";
201 #endif /* G_NATIVE_ATEXIT */
202
203   if (error)
204     g_error ("Could not register atexit() function: %s", error);
205 }
206
207 /* Based on execvp() from GNU Libc.
208  * Some of this code is cut-and-pasted into gspawn.c
209  */
210
211 static gchar*
212 my_strchrnul (const gchar *str, gchar c)
213 {
214   gchar *p = (gchar*)str;
215   while (*p && (*p != c))
216     ++p;
217
218   return p;
219 }
220
221 #ifdef G_OS_WIN32
222
223 static gchar *inner_find_program_in_path (const gchar *program);
224
225 gchar*
226 g_find_program_in_path (const gchar *program)
227 {
228   const gchar *last_dot = strrchr (program, '.');
229
230   if (last_dot == NULL || strchr (last_dot, '\\') != NULL)
231     {
232       const gint program_length = strlen (program);
233       const gchar *pathext = getenv ("PATHEXT");
234       const gchar *p;
235       gchar *decorated_program;
236       gchar *retval;
237
238       if (pathext == NULL)
239         pathext = ".com;.exe;.bat";
240
241       p = pathext;
242       do
243         {
244           pathext = p;
245           p = my_strchrnul (pathext, ';');
246
247           decorated_program = g_malloc (program_length + (p-pathext) + 1);
248           memcpy (decorated_program, program, program_length);
249           memcpy (decorated_program+program_length, pathext, p-pathext);
250           decorated_program [program_length + (p-pathext)] = '\0';
251           
252           retval = inner_find_program_in_path (decorated_program);
253           g_free (decorated_program);
254
255           if (retval != NULL)
256             return retval;
257         } while (*p++ != '\0');
258       return NULL;
259     }
260   else
261     return inner_find_program_in_path (program);
262 }
263
264 #define g_find_program_in_path inner_find_program_in_path
265 #endif
266
267 /**
268  * g_find_program_in_path:
269  * @program: a program name
270  * 
271  * Locates the first executable named @program in the user's path, in the
272  * same way that execvp() would locate it. Returns an allocated string
273  * with the absolute path name, or NULL if the program is not found in
274  * the path. If @program is already an absolute path, returns a copy of
275  * @program if @program exists and is executable, and NULL otherwise.
276  * 
277  * On Windows, if @program does not have a file type suffix, tries to
278  * append the suffixes in the PATHEXT environment variable (if that
279  * doesn't exists, the suffixes .com, .exe, and .bat) in turn, and
280  * then look for the resulting file name in the same way as
281  * CreateProcess() would. This means first in the directory where the
282  * program was loaded from, then in the current directory, then in the
283  * Windows 32-bit system directory, then in the Windows directory, and
284  * finally in the directories in the PATH environment variable. If
285  * the program is found, the return value contains the full name
286  * including the type suffix.
287  *
288  * Return value: absolute path, or NULL
289  **/
290 #ifdef G_OS_WIN32
291 static
292 #endif
293 gchar*
294 g_find_program_in_path (const gchar *program)
295 {
296   const gchar *path, *p;
297   gchar *name, *freeme;
298 #ifdef G_OS_WIN32
299   gchar *path_tmp;
300 #endif
301   size_t len;
302   size_t pathlen;
303
304   g_return_val_if_fail (program != NULL, NULL);
305
306   /* If it is an absolute path, or a relative path including subdirectories,
307    * don't look in PATH.
308    */
309   if (g_path_is_absolute (program)
310       || strchr (program, G_DIR_SEPARATOR) != NULL
311 #ifdef G_OS_WIN32
312       || strchr (program, '/') != NULL
313 #endif
314       )
315     {
316       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE))
317         return g_strdup (program);
318       else
319         return NULL;
320     }
321   
322   path = g_getenv ("PATH");
323 #ifdef G_OS_UNIX
324   if (path == NULL)
325     {
326       /* There is no `PATH' in the environment.  The default
327        * search path in GNU libc is the current directory followed by
328        * the path `confstr' returns for `_CS_PATH'.
329        */
330       
331       /* In GLib we put . last, for security, and don't use the
332        * unportable confstr(); UNIX98 does not actually specify
333        * what to search if PATH is unset. POSIX may, dunno.
334        */
335       
336       path = "/bin:/usr/bin:.";
337     }
338 #else
339   {
340     gchar *tmp;
341     gchar moddir[MAXPATHLEN], sysdir[MAXPATHLEN], windir[MAXPATHLEN];
342
343     GetModuleFileName (NULL, moddir, sizeof (moddir));
344     tmp = g_path_get_dirname (moddir);
345     GetSystemDirectory (sysdir, sizeof (sysdir));
346     GetWindowsDirectory (windir, sizeof (windir));
347     path_tmp = g_strconcat (tmp, ";.;", sysdir, ";", windir,
348                             (path != NULL ? ";" : NULL),
349                             (path != NULL ? path : NULL),
350                             NULL);
351     g_free (tmp);
352     path = path_tmp;
353   }
354 #endif
355   
356   len = strlen (program) + 1;
357   pathlen = strlen (path);
358   freeme = name = g_malloc (pathlen + len + 1);
359   
360   /* Copy the file name at the top, including '\0'  */
361   memcpy (name + pathlen + 1, program, len);
362   name = name + pathlen;
363   /* And add the slash before the filename  */
364   *name = G_DIR_SEPARATOR;
365   
366   p = path;
367   do
368     {
369       char *startp;
370
371       path = p;
372       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
373
374       if (p == path)
375         /* Two adjacent colons, or a colon at the beginning or the end
376          * of `PATH' means to search the current directory.
377          */
378         startp = name + 1;
379       else
380         startp = memcpy (name - (p - path), path, p - path);
381
382       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE))
383         {
384           gchar *ret;
385           ret = g_strdup (startp);
386           g_free (freeme);
387 #ifdef G_OS_WIN32
388           g_free (path_tmp);
389 #endif
390           return ret;
391         }
392     }
393   while (*p++ != '\0');
394   
395   g_free (freeme);
396 #ifdef G_OS_WIN32
397   g_free (path_tmp);
398 #endif
399
400   return NULL;
401 }
402
403 guint        
404 g_parse_debug_string  (const gchar     *string, 
405                        const GDebugKey *keys, 
406                        guint            nkeys)
407 {
408   guint i;
409   guint result = 0;
410   
411   g_return_val_if_fail (string != NULL, 0);
412   
413   if (!g_ascii_strcasecmp (string, "all"))
414     {
415       for (i=0; i<nkeys; i++)
416         result |= keys[i].value;
417     }
418   else
419     {
420       const gchar *p = string;
421       const gchar *q;
422       gboolean done = FALSE;
423       
424       while (*p && !done)
425         {
426           q = strchr (p, ':');
427           if (!q)
428             {
429               q = p + strlen(p);
430               done = TRUE;
431             }
432           
433           for (i=0; i<nkeys; i++)
434             if (g_ascii_strncasecmp(keys[i].key, p, q - p) == 0 &&
435                 keys[i].key[q - p] == '\0')
436               result |= keys[i].value;
437           
438           p = q + 1;
439         }
440     }
441   
442   return result;
443 }
444
445 /**
446  * g_basename:
447  * @file_name: the name of the file.
448  * 
449  * Gets the name of the file without any leading directory components.  
450  * It returns a pointer into the given file name string.
451  * 
452  * Return value: the name of the file without any leading directory components.
453  *
454  * Deprecated: Use g_path_get_basename() instead, but notice that
455  * g_path_get_basename() allocates new memory for the returned string, unlike
456  * this function which returns a pointer into the argument.
457  **/
458 G_CONST_RETURN gchar*
459 g_basename (const gchar    *file_name)
460 {
461   register gchar *base;
462   
463   g_return_val_if_fail (file_name != NULL, NULL);
464   
465   base = strrchr (file_name, G_DIR_SEPARATOR);
466
467 #ifdef G_OS_WIN32
468   {
469     gchar *q = strrchr (file_name, '/');
470     if (base == NULL || (q != NULL && q > base))
471         base = q;
472   }
473 #endif
474
475   if (base)
476     return base + 1;
477
478 #ifdef G_OS_WIN32
479   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
480     return (gchar*) file_name + 2;
481 #endif /* G_OS_WIN32 */
482   
483   return (gchar*) file_name;
484 }
485
486 /**
487  * g_path_get_basename:
488  * @file_name: the name of the file.
489  *
490  * Gets the last component of the filename. If @file_name ends with a 
491  * directory separator it gets the component before the last slash. If 
492  * @file_name consists only of directory separators (and on Windows, 
493  * possibly a drive letter), a single separator is returned. If
494  * @file_name is empty, it gets ".".
495  *
496  * Return value: a newly allocated string containing the last component of 
497  *   the filename.
498  */
499 gchar*
500 g_path_get_basename (const gchar   *file_name)
501 {
502   register gssize base;             
503   register gssize last_nonslash;    
504   gsize len;    
505   gchar *retval;
506  
507   g_return_val_if_fail (file_name != NULL, NULL);
508
509   if (file_name[0] == '\0')
510     /* empty string */
511     return g_strdup (".");
512   
513   last_nonslash = strlen (file_name) - 1;
514
515   while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
516     last_nonslash--;
517
518   if (last_nonslash == -1)
519     /* string only containing slashes */
520     return g_strdup (G_DIR_SEPARATOR_S);
521
522 #ifdef G_OS_WIN32
523   if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
524     /* string only containing slashes and a drive */
525     return g_strdup (G_DIR_SEPARATOR_S);
526 #endif /* G_OS_WIN32 */
527
528   base = last_nonslash;
529
530   while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
531     base--;
532
533 #ifdef G_OS_WIN32
534   if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
535     base = 1;
536 #endif /* G_OS_WIN32 */
537
538   len = last_nonslash - base;
539   retval = g_malloc (len + 1);
540   memcpy (retval, file_name + base + 1, len);
541   retval [len] = '\0';
542   return retval;
543 }
544
545 gboolean
546 g_path_is_absolute (const gchar *file_name)
547 {
548   g_return_val_if_fail (file_name != NULL, FALSE);
549   
550   if (G_IS_DIR_SEPARATOR (file_name[0]))
551     return TRUE;
552
553 #ifdef G_OS_WIN32
554   /* Recognize drive letter on native Windows */
555   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
556     return TRUE;
557 #endif /* G_OS_WIN32 */
558
559   return FALSE;
560 }
561
562 G_CONST_RETURN gchar*
563 g_path_skip_root (const gchar *file_name)
564 {
565   g_return_val_if_fail (file_name != NULL, NULL);
566   
567 #ifdef G_PLATFORM_WIN32
568   /* Skip \\server\share or //server/share */
569   if (G_IS_DIR_SEPARATOR (file_name[0]) &&
570       G_IS_DIR_SEPARATOR (file_name[1]) &&
571       file_name[2])
572     {
573       gchar *p;
574
575       p = strchr (file_name + 2, G_DIR_SEPARATOR);
576 #ifdef G_OS_WIN32
577       {
578         gchar *q = strchr (file_name + 2, '/');
579         if (p == NULL || (q != NULL && q < p))
580           p = q;
581       }
582 #endif
583       if (p &&
584           p > file_name + 2 &&
585           p[1])
586         {
587           file_name = p + 1;
588
589           while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
590             file_name++;
591
592           /* Possibly skip a backslash after the share name */
593           if (G_IS_DIR_SEPARATOR (file_name[0]))
594             file_name++;
595
596           return (gchar *)file_name;
597         }
598     }
599 #endif
600   
601   /* Skip initial slashes */
602   if (G_IS_DIR_SEPARATOR (file_name[0]))
603     {
604       while (G_IS_DIR_SEPARATOR (file_name[0]))
605         file_name++;
606       return (gchar *)file_name;
607     }
608
609 #ifdef G_OS_WIN32
610   /* Skip X:\ */
611   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
612     return (gchar *)file_name + 3;
613 #endif
614
615   return NULL;
616 }
617
618 gchar*
619 g_path_get_dirname (const gchar    *file_name)
620 {
621   register gchar *base;
622   register gsize len;    
623   
624   g_return_val_if_fail (file_name != NULL, NULL);
625   
626   base = strrchr (file_name, G_DIR_SEPARATOR);
627 #ifdef G_OS_WIN32
628   {
629     gchar *q = strrchr (file_name, '/');
630     if (base == NULL || (q != NULL && q > base))
631         base = q;
632   }
633 #endif
634   if (!base)
635     {
636 #ifdef G_OS_WIN32
637       if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
638         {
639           gchar drive_colon_dot[4];
640
641           drive_colon_dot[0] = file_name[0];
642           drive_colon_dot[1] = ':';
643           drive_colon_dot[2] = '.';
644           drive_colon_dot[3] = '\0';
645
646           return g_strdup (drive_colon_dot);
647         }
648 #endif
649     return g_strdup (".");
650     }
651
652   while (base > file_name && G_IS_DIR_SEPARATOR (*base))
653     base--;
654
655 #ifdef G_OS_WIN32
656   if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
657       base++;
658 #endif
659
660   len = (guint) 1 + base - file_name;
661   
662   base = g_new (gchar, len + 1);
663   g_memmove (base, file_name, len);
664   base[len] = 0;
665   
666   return base;
667 }
668
669 gchar*
670 g_get_current_dir (void)
671 {
672   gchar *buffer = NULL;
673   gchar *dir = NULL;
674   static gulong max_len = 0;
675
676   if (max_len == 0) 
677     max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
678   
679   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
680    * and, if that wasn't bad enough, hangs in doing so.
681    */
682 #if     (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
683   buffer = g_new (gchar, max_len + 1);
684   *buffer = 0;
685   dir = getwd (buffer);
686 #else   /* !sun || !HAVE_GETCWD */
687   while (max_len < G_MAXULONG / 2)
688     {
689       buffer = g_new (gchar, max_len + 1);
690       *buffer = 0;
691       dir = getcwd (buffer, max_len);
692
693       if (dir || errno != ERANGE)
694         break;
695
696       g_free (buffer);
697       max_len *= 2;
698     }
699 #endif  /* !sun || !HAVE_GETCWD */
700   
701   if (!dir || !*buffer)
702     {
703       /* hm, should we g_error() out here?
704        * this can happen if e.g. "./" has mode \0000
705        */
706       buffer[0] = G_DIR_SEPARATOR;
707       buffer[1] = 0;
708     }
709
710   dir = g_strdup (buffer);
711   g_free (buffer);
712   
713   return dir;
714 }
715
716 /**
717  * g_getenv:
718  * @variable: the environment variable to get.
719  * 
720  * Returns an environment variable.
721  * 
722  * Return value: the value of the environment variable, or %NULL if the environment
723  * variable is not found. The returned string may be overwritten by the next call to g_getenv(),
724  * g_setenv() or g_unsetenv().
725  **/
726 G_CONST_RETURN gchar*
727 g_getenv (const gchar *variable)
728 {
729 #ifndef G_OS_WIN32
730   g_return_val_if_fail (variable != NULL, NULL);
731
732   return getenv (variable);
733 #else
734   GQuark quark;
735   gchar *system_env;
736   gchar *expanded_env;
737   guint length;
738   gchar dummy[2];
739
740   g_return_val_if_fail (variable != NULL, NULL);
741   
742   system_env = getenv (variable);
743   if (!system_env)
744     return NULL;
745
746   /* On Windows NT, it is relatively typical that environment
747    * variables contain references to other environment variables. If
748    * so, use ExpandEnvironmentStrings(). (If all software was written
749    * in the best possible way, such environment variables would be
750    * stored in the Registry as REG_EXPAND_SZ type values, and would
751    * then get automatically expanded before the program sees them. But
752    * there is broken software that stores environment variables as
753    * REG_SZ values even if they contain references to other
754    * environment variables.
755    */
756
757   if (strchr (system_env, '%') == NULL)
758     {
759       /* No reference to other variable(s), return value as such. */
760       return system_env;
761     }
762
763   /* First check how much space we need */
764   length = ExpandEnvironmentStrings (system_env, dummy, 2);
765   
766   expanded_env = g_malloc (length);
767   
768   ExpandEnvironmentStrings (system_env, expanded_env, length);
769   
770   quark = g_quark_from_string (expanded_env);
771   g_free (expanded_env);
772   
773   return g_quark_to_string (quark);
774 #endif
775 }
776
777 /**
778  * g_setenv:
779  * @variable: the environment variable to set, must not contain '='.
780  * @value: the value for to set the variable to.
781  * @overwrite: whether to change the variable if it already exists.
782  *
783  * Sets an environment variable.
784  *
785  * Note that on some systems, the memory used for the variable and its value 
786  * can't be reclaimed later.
787  *
788  * Returns: %FALSE if the environment variable couldn't be set.
789  *
790  * Since: 2.4
791  */
792 gboolean
793 g_setenv (const gchar *variable, 
794           const gchar *value, 
795           gboolean     overwrite)
796 {
797   gint result;
798 #ifndef HAVE_SETENV
799   gchar *string;
800 #endif
801
802   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
803
804 #ifdef HAVE_SETENV
805   result = setenv (variable, value, overwrite);
806 #else
807   if (!overwrite && g_getenv (variable) != NULL)
808     return TRUE;
809   
810   /* This results in a leak when you overwrite existing
811    * settings. It would be fairly easy to fix this by keeping
812    * our own parallel array or hash table.
813    */
814   string = g_strconcat (variable, "=", value, NULL);
815   result = putenv (string);
816 #endif
817   return result == 0;
818 }
819
820 #ifndef HAVE_UNSETENV     
821 /* According to the Single Unix Specification, environ is not in 
822  * any system header, although unistd.h often declares it.
823  */
824 #  ifndef _MSC_VER
825 /*
826  * Win32 - at least msvc headers declare it so let's avoid
827  *   warning C4273: '__p__environ' : inconsistent dll linkage.  dllexport assumed.
828  */
829 extern char **environ;
830 #  endif
831 #endif
832            
833 /**
834  * g_unsetenv:
835  * @variable: the environment variable to remove, must not contain '='.
836  * 
837  * Removes an environment variable from the environment.
838  *
839  * Note that on some systems, the memory used for the variable and its value 
840  * can't be reclaimed. Furthermore, this function can't be guaranteed to operate in a 
841  * threadsafe way.
842  *
843  * Since: 2.4 
844  **/
845 void
846 g_unsetenv (const gchar *variable)
847 {
848 #ifdef HAVE_UNSETENV
849   g_return_if_fail (strchr (variable, '=') == NULL);
850
851   unsetenv (variable);
852 #else
853   int len;
854   gchar **e, **f;
855
856   g_return_if_fail (strchr (variable, '=') == NULL);
857
858   len = strlen (variable);
859   
860   /* Mess directly with the environ array.
861    * This seems to be the only portable way to do this.
862    *
863    * Note that we remove *all* environment entries for
864    * the variable name, not just the first.
865    */
866   e = f = environ;
867   while (*e != NULL) 
868     {
869       if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
870         {
871           *f = *e;
872           f++;
873         }
874       e++;
875     }
876   *f = NULL;
877 #endif
878 }
879
880 G_LOCK_DEFINE_STATIC (g_utils_global);
881
882 static  gchar   *g_tmp_dir = NULL;
883 static  gchar   *g_user_name = NULL;
884 static  gchar   *g_real_name = NULL;
885 static  gchar   *g_home_dir = NULL;
886
887 /* HOLDS: g_utils_global_lock */
888 static void
889 g_get_any_init (void)
890 {
891   if (!g_tmp_dir)
892     {
893       g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
894       if (!g_tmp_dir)
895         g_tmp_dir = g_strdup (g_getenv ("TMP"));
896       if (!g_tmp_dir)
897         g_tmp_dir = g_strdup (g_getenv ("TEMP"));
898       
899 #ifdef P_tmpdir
900       if (!g_tmp_dir)
901         {
902           gsize k;    
903           g_tmp_dir = g_strdup (P_tmpdir);
904           k = strlen (g_tmp_dir);
905           if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
906             g_tmp_dir[k - 1] = '\0';
907         }
908 #endif
909       
910       if (!g_tmp_dir)
911         {
912 #ifndef G_OS_WIN32
913           g_tmp_dir = g_strdup ("/tmp");
914 #else /* G_OS_WIN32 */
915           g_tmp_dir = g_strdup ("C:\\");
916 #endif /* G_OS_WIN32 */
917         }
918       
919 #ifdef G_OS_WIN32
920       /* We check $HOME first for Win32, though it is a last resort for Unix
921        * where we prefer the results of getpwuid().
922        */
923       {
924         gchar *home = g_getenv ("HOME");
925       
926         /* Only believe HOME if it is an absolute path and exists */
927         if (home && g_path_is_absolute (home) && g_file_test (home, G_FILE_TEST_IS_DIR))
928           g_home_dir = g_strdup (home);
929       }
930       
931       /* In case HOME is Unix-style (it happens), convert it to
932        * Windows style.
933        */
934       if (g_home_dir)
935         {
936           gchar *p;
937           while ((p = strchr (g_home_dir, '/')) != NULL)
938             *p = '\\';
939         }
940
941       if (!g_home_dir)
942         {
943           /* USERPROFILE is probably the closest equivalent to $HOME? */
944           if (getenv ("USERPROFILE") != NULL)
945             g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
946         }
947
948       if (!g_home_dir)
949         {
950           /* At least at some time, HOMEDRIVE and HOMEPATH were used
951            * to point to the home directory, I think. But on Windows
952            * 2000 HOMEDRIVE seems to be equal to SYSTEMDRIVE, and
953            * HOMEPATH is its root "\"?
954            */
955           if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
956             {
957               gchar *homedrive, *homepath;
958               
959               homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
960               homepath = g_strdup (g_getenv ("HOMEPATH"));
961               
962               g_home_dir = g_strconcat (homedrive, homepath, NULL);
963               g_free (homedrive);
964               g_free (homepath);
965             }
966         }
967 #endif /* G_OS_WIN32 */
968       
969 #ifdef HAVE_PWD_H
970       {
971         struct passwd *pw = NULL;
972         gpointer buffer = NULL;
973         gint error;
974         
975 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
976         struct passwd pwd;
977 #    ifdef _SC_GETPW_R_SIZE_MAX  
978         /* This reurns the maximum length */
979         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
980         
981         if (bufsize < 0)
982           bufsize = 64;
983 #    else /* _SC_GETPW_R_SIZE_MAX */
984         glong bufsize = 64;
985 #    endif /* _SC_GETPW_R_SIZE_MAX */
986         
987         do
988           {
989             g_free (buffer);
990             buffer = g_malloc (bufsize);
991             errno = 0;
992             
993 #    ifdef HAVE_POSIX_GETPWUID_R
994             error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
995             error = error < 0 ? errno : error;
996 #    else /* HAVE_NONPOSIX_GETPWUID_R */
997        /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
998 #      if defined(_AIX) || defined(__hpux)
999             error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1000             pw = error == 0 ? &pwd : NULL;
1001 #      else /* !_AIX */
1002             pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1003             error = pw ? 0 : errno;
1004 #      endif /* !_AIX */            
1005 #    endif /* HAVE_NONPOSIX_GETPWUID_R */
1006             
1007             if (!pw)
1008               {
1009                 /* we bail out prematurely if the user id can't be found
1010                  * (should be pretty rare case actually), or if the buffer
1011                  * should be sufficiently big and lookups are still not
1012                  * successfull.
1013                  */
1014                 if (error == 0 || error == ENOENT)
1015                   {
1016                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
1017                                (gulong) getuid ());
1018                     break;
1019                   }
1020                 if (bufsize > 32 * 1024)
1021                   {
1022                     g_warning ("getpwuid_r(): failed due to: %s.",
1023                                g_strerror (error));
1024                     break;
1025                   }
1026                 
1027                 bufsize *= 2;
1028               }
1029           }
1030         while (!pw);
1031 #  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
1032         
1033         if (!pw)
1034           {
1035             setpwent ();
1036             pw = getpwuid (getuid ());
1037             endpwent ();
1038           }
1039         if (pw)
1040           {
1041             g_user_name = g_strdup (pw->pw_name);
1042
1043             if (pw->pw_gecos && *pw->pw_gecos != '\0') 
1044               {
1045                 gchar **gecos_fields;
1046                 gchar **name_parts;
1047
1048                 /* split the gecos field and substitute '&' */
1049                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
1050                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
1051                 pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
1052                 g_real_name = g_strjoinv (pw->pw_name, name_parts);
1053                 g_strfreev (gecos_fields);
1054                 g_strfreev (name_parts);
1055               }
1056
1057             if (!g_home_dir)
1058               g_home_dir = g_strdup (pw->pw_dir);
1059           }
1060         g_free (buffer);
1061       }
1062       
1063 #else /* !HAVE_PWD_H */
1064       
1065 #  ifdef G_OS_WIN32
1066       {
1067         guint len = UNLEN+1;
1068         gchar buffer[UNLEN+1];
1069         
1070         if (GetUserName ((LPTSTR) buffer, (LPDWORD) &len))
1071           {
1072             g_user_name = g_strdup (buffer);
1073             g_real_name = g_strdup (buffer);
1074           }
1075       }
1076 #  endif /* G_OS_WIN32 */
1077
1078 #endif /* !HAVE_PWD_H */
1079
1080       if (!g_home_dir)
1081         g_home_dir = g_strdup (g_getenv ("HOME"));
1082       
1083 #ifdef __EMX__
1084       /* change '\\' in %HOME% to '/' */
1085       g_strdelimit (g_home_dir, "\\",'/');
1086 #endif
1087       if (!g_user_name)
1088         g_user_name = g_strdup ("somebody");
1089       if (!g_real_name)
1090         g_real_name = g_strdup ("Unknown");
1091     }
1092 }
1093
1094 G_CONST_RETURN gchar*
1095 g_get_user_name (void)
1096 {
1097   G_LOCK (g_utils_global);
1098   if (!g_tmp_dir)
1099     g_get_any_init ();
1100   G_UNLOCK (g_utils_global);
1101   
1102   return g_user_name;
1103 }
1104
1105 G_CONST_RETURN gchar*
1106 g_get_real_name (void)
1107 {
1108   G_LOCK (g_utils_global);
1109   if (!g_tmp_dir)
1110     g_get_any_init ();
1111   G_UNLOCK (g_utils_global);
1112  
1113   return g_real_name;
1114 }
1115
1116 /* Return the home directory of the user. If there is a HOME
1117  * environment variable, its value is returned, otherwise use some
1118  * system-dependent way of finding it out. If no home directory can be
1119  * deduced, return NULL.
1120  */
1121
1122 G_CONST_RETURN gchar*
1123 g_get_home_dir (void)
1124 {
1125   G_LOCK (g_utils_global);
1126   if (!g_tmp_dir)
1127     g_get_any_init ();
1128   G_UNLOCK (g_utils_global);
1129   
1130   return g_home_dir;
1131 }
1132
1133 /* Return a directory to be used to store temporary files. This is the
1134  * value of the TMPDIR, TMP or TEMP environment variables (they are
1135  * checked in that order). If none of those exist, use P_tmpdir from
1136  * stdio.h.  If that isn't defined, return "/tmp" on POSIXly systems,
1137  * and C:\ on Windows.
1138  */
1139
1140 G_CONST_RETURN gchar*
1141 g_get_tmp_dir (void)
1142 {
1143   G_LOCK (g_utils_global);
1144   if (!g_tmp_dir)
1145     g_get_any_init ();
1146   G_UNLOCK (g_utils_global);
1147   
1148   return g_tmp_dir;
1149 }
1150
1151 G_LOCK_DEFINE_STATIC (g_prgname);
1152 static gchar *g_prgname = NULL;
1153
1154 gchar*
1155 g_get_prgname (void)
1156 {
1157   gchar* retval;
1158
1159   G_LOCK (g_prgname);
1160   retval = g_prgname;
1161   G_UNLOCK (g_prgname);
1162
1163   return retval;
1164 }
1165
1166 void
1167 g_set_prgname (const gchar *prgname)
1168 {
1169   G_LOCK (g_prgname);
1170   g_free (g_prgname);
1171   g_prgname = g_strdup (prgname);
1172   G_UNLOCK (g_prgname);
1173 }
1174
1175 G_LOCK_DEFINE_STATIC (g_application_name);
1176 static gchar *g_application_name = NULL;
1177
1178 /**
1179  * g_get_application_name:
1180  * 
1181  * Gets a human-readable name for the application, as set by
1182  * g_set_application_name(). This name should be localized if
1183  * possible, and is intended for display to the user.  Contrast with
1184  * g_get_prgname(), which gets a non-localized name. If
1185  * g_set_application_name() has not been called, returns the result of
1186  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1187  * been called).
1188  * 
1189  * Return value: human-readable application name. may return %NULL
1190  *
1191  * Since: 2.2
1192  **/
1193 G_CONST_RETURN gchar*
1194 g_get_application_name (void)
1195 {
1196   gchar* retval;
1197
1198   G_LOCK (g_application_name);
1199   retval = g_application_name;
1200   G_UNLOCK (g_application_name);
1201
1202   if (retval == NULL)
1203     return g_get_prgname ();
1204   
1205   return retval;
1206 }
1207
1208 /**
1209  * g_set_application_name:
1210  * @application_name: localized name of the application
1211  *
1212  * Sets a human-readable name for the application. This name should be
1213  * localized if possible, and is intended for display to the user.
1214  * Contrast with g_set_prgname(), which sets a non-localized name.
1215  * g_set_prgname() will be called automatically by gtk_init(),
1216  * but g_set_application_name() will not.
1217  *
1218  * Note that for thread safety reasons, this function can only
1219  * be called once.
1220  *
1221  * The application name will be used in contexts such as error messages,
1222  * or when displaying an application's name in the task list.
1223  * 
1224  **/
1225 void
1226 g_set_application_name (const gchar *application_name)
1227 {
1228   gboolean already_set = FALSE;
1229         
1230   G_LOCK (g_application_name);
1231   if (g_application_name)
1232     already_set = TRUE;
1233   else
1234     g_application_name = g_strdup (application_name);
1235   G_UNLOCK (g_application_name);
1236
1237   if (already_set)
1238     g_warning ("g_set_application() name called multiple times");
1239 }
1240
1241 guint
1242 g_direct_hash (gconstpointer v)
1243 {
1244   return GPOINTER_TO_UINT (v);
1245 }
1246
1247 gboolean
1248 g_direct_equal (gconstpointer v1,
1249                 gconstpointer v2)
1250 {
1251   return v1 == v2;
1252 }
1253
1254 gboolean
1255 g_int_equal (gconstpointer v1,
1256              gconstpointer v2)
1257 {
1258   return *((const gint*) v1) == *((const gint*) v2);
1259 }
1260
1261 guint
1262 g_int_hash (gconstpointer v)
1263 {
1264   return *(const gint*) v;
1265 }
1266
1267 /**
1268  * g_nullify_pointer:
1269  * @nullify_location: the memory address of the pointer.
1270  * 
1271  * Set the pointer at the specified location to %NULL.
1272  **/
1273 void
1274 g_nullify_pointer (gpointer *nullify_location)
1275 {
1276   g_return_if_fail (nullify_location != NULL);
1277
1278   *nullify_location = NULL;
1279 }
1280
1281 /**
1282  * g_get_codeset:
1283  * 
1284  * Get the codeset for the current locale.
1285  * 
1286  * Return value: a newly allocated string containing the name
1287  * of the codeset. This string must be freed with g_free().
1288  **/
1289 gchar *
1290 g_get_codeset (void)
1291 {
1292   const gchar *charset;
1293
1294   g_get_charset (&charset);
1295
1296   return g_strdup (charset);
1297 }
1298
1299 #ifdef ENABLE_NLS
1300
1301 #include <libintl.h>
1302
1303 #ifdef G_PLATFORM_WIN32
1304
1305 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
1306
1307 static const gchar *
1308 _glib_get_locale_dir (void)
1309 {
1310   static const gchar *cache = NULL;
1311   if (cache == NULL)
1312     cache = g_win32_get_package_installation_subdirectory
1313       (GETTEXT_PACKAGE, dll_name, "lib\\locale");
1314
1315   return cache;
1316 }
1317
1318 #undef GLIB_LOCALE_DIR
1319 #define GLIB_LOCALE_DIR _glib_get_locale_dir ()
1320
1321 #endif /* G_PLATFORM_WIN32 */
1322
1323 G_CONST_RETURN gchar *
1324 _glib_gettext (const gchar *str)
1325 {
1326   static gboolean _glib_gettext_initialized = FALSE;
1327
1328   if (!_glib_gettext_initialized)
1329     {
1330       bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
1331 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1332       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1333 #    endif
1334       _glib_gettext_initialized = TRUE;
1335     }
1336   
1337   return dgettext (GETTEXT_PACKAGE, str);
1338 }
1339
1340 #endif /* ENABLE_NLS */