gutils.c 18.1 KB
Newer Older
Owen Taylor's avatar
Owen Taylor committed
1
/* GLIB - Library of useful routines for C programming
2
 * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
Owen Taylor's avatar
Owen Taylor committed
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
Owen Taylor's avatar
Owen Taylor committed
6 7 8 9 10 11
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12
 * Lesser General Public License for more details.
Owen Taylor's avatar
Owen Taylor committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Owen Taylor's avatar
Owen Taylor committed
15 16 17 18
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
19

20
/*
21
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22 23 24 25 26
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

27 28 29 30
/* 
 * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
 */

31 32 33 34
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

35
#ifdef HAVE_UNISTD_H
36
#include <unistd.h>
37
#endif
Owen Taylor's avatar
Owen Taylor committed
38 39
#include <stdarg.h>
#include <stdlib.h>
40
#include <stdio.h>
Owen Taylor's avatar
Owen Taylor committed
41
#include <string.h>
Manish Singh's avatar
Manish Singh committed
42
#include <errno.h>
43
#ifdef HAVE_PWD_H
44
#include <pwd.h>
45
#endif
46
#include <sys/types.h>
47
#ifdef HAVE_SYS_PARAM_H
48
#include <sys/param.h>
49 50
#endif

51 52
/* implement Glib's inline functions
 */
53 54
#define	G_IMPLEMENT_INLINES 1
#define	__G_UTILS_C__
Owen Taylor's avatar
Owen Taylor committed
55 56
#include "glib.h"

57
#ifdef	MAXPATHLEN
58
#define	G_PATH_LENGTH	MAXPATHLEN
59
#elif	defined (PATH_MAX)
60 61 62 63 64 65
#define	G_PATH_LENGTH	PATH_MAX
#elif   defined (_PC_PATH_MAX)
#define	G_PATH_LENGTH	sysconf(_PC_PATH_MAX)
#else	
#define G_PATH_LENGTH   2048
#endif
66

67 68 69 70 71 72 73 74
#ifdef G_OS_WIN32
#  define STRICT			/* Strict typing, please */
#  include <windows.h>
#  include <ctype.h>
#  include <direct.h>
#  include <io.h>
#endif /* G_OS_WIN32 */

75 76 77 78
#ifdef HAVE_CODESET
#include <langinfo.h>
#endif

Owen Taylor's avatar
Owen Taylor committed
79 80 81
const guint glib_major_version = GLIB_MAJOR_VERSION;
const guint glib_minor_version = GLIB_MINOR_VERSION;
const guint glib_micro_version = GLIB_MICRO_VERSION;
82 83
const guint glib_interface_age = GLIB_INTERFACE_AGE;
const guint glib_binary_age = GLIB_BINARY_AGE;
Owen Taylor's avatar
Owen Taylor committed
84

85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
#if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
void 
g_memmove (gpointer dest, gconstpointer src, gulong len)
{
  gchar* destptr = dest;
  const gchar* srcptr = src;
  if (src + len < dest || dest + len < src)
    {
      bcopy (src, dest, len);
      return;
    }
  else if (dest <= src)
    {
      while (len--)
	*(destptr++) = *(srcptr++);
    }
  else
    {
      destptr += len;
      srcptr += len;
      while (len--)
	*(--destptr) = *(--srcptr);
    }
}
#endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
void
g_atexit (GVoidFunc func)
{
  gint result;
  gchar *error = NULL;

  /* keep this in sync with glib.h */

#ifdef	G_NATIVE_ATEXIT
  result = ATEXIT (func);
  if (result)
    error = g_strerror (errno);
#elif defined (HAVE_ATEXIT)
#  ifdef NeXT /* @#%@! NeXTStep */
  result = !atexit ((void (*)(void)) func);
  if (result)
    error = g_strerror (errno);
#  else
  result = atexit ((void (*)(void)) func);
  if (result)
    error = g_strerror (errno);
#  endif /* NeXT */
#elif defined (HAVE_ON_EXIT)
  result = on_exit ((void (*)(int, void *)) func, NULL);
  if (result)
    error = g_strerror (errno);
#else
  result = 0;
  error = "no implementation";
#endif /* G_NATIVE_ATEXIT */

  if (error)
    g_error ("Could not register atexit() function: %s", error);
}

Owen Taylor's avatar
Owen Taylor committed
146
gint
147 148
g_snprintf (gchar	*str,
	    gulong	 n,
Owen Taylor's avatar
Owen Taylor committed
149 150 151
	    gchar const *fmt,
	    ...)
{
152
#ifdef	HAVE_VSNPRINTF
Owen Taylor's avatar
Owen Taylor committed
153 154 155
  va_list args;
  gint retval;
  
Tim Janik's avatar
Tim Janik committed
156 157 158 159
  g_return_val_if_fail (str != NULL, 0);
  g_return_val_if_fail (n > 0, 0);
  g_return_val_if_fail (fmt != NULL, 0);

Owen Taylor's avatar
Owen Taylor committed
160 161 162
  va_start (args, fmt);
  retval = vsnprintf (str, n, fmt, args);
  va_end (args);
163 164 165 166 167 168 169

  if (retval < 0)
    {
      str[n-1] = '\0';
      retval = strlen (str);
    }

Owen Taylor's avatar
Owen Taylor committed
170
  return retval;
171
#else	/* !HAVE_VSNPRINTF */
Owen Taylor's avatar
Owen Taylor committed
172
  gchar *printed;
173
  va_list args;
174
  
Tim Janik's avatar
Tim Janik committed
175 176 177 178
  g_return_val_if_fail (str != NULL, 0);
  g_return_val_if_fail (n > 0, 0);
  g_return_val_if_fail (fmt != NULL, 0);

Owen Taylor's avatar
Owen Taylor committed
179
  va_start (args, fmt);
180 181
  printed = g_strdup_vprintf (fmt, args);
  va_end (args);
Owen Taylor's avatar
Owen Taylor committed
182 183 184
  
  strncpy (str, printed, n);
  str[n-1] = '\0';
185 186

  g_free (printed);
187
  
Owen Taylor's avatar
Owen Taylor committed
188
  return strlen (str);
189 190 191 192 193 194 195
#endif	/* !HAVE_VSNPRINTF */
}

gint
g_vsnprintf (gchar	 *str,
	     gulong	  n,
	     gchar const *fmt,
196
	     va_list      args)
197 198 199 200
{
#ifdef	HAVE_VSNPRINTF
  gint retval;
  
Tim Janik's avatar
Tim Janik committed
201 202 203 204
  g_return_val_if_fail (str != NULL, 0);
  g_return_val_if_fail (n > 0, 0);
  g_return_val_if_fail (fmt != NULL, 0);

205
  retval = vsnprintf (str, n, fmt, args);
206
  
207 208 209 210 211 212
  if (retval < 0)
    {
      str[n-1] = '\0';
      retval = strlen (str);
    }

213 214 215 216
  return retval;
#else	/* !HAVE_VSNPRINTF */
  gchar *printed;
  
Tim Janik's avatar
Tim Janik committed
217 218 219 220
  g_return_val_if_fail (str != NULL, 0);
  g_return_val_if_fail (n > 0, 0);
  g_return_val_if_fail (fmt != NULL, 0);

221
  printed = g_strdup_vprintf (fmt, args);
222 223
  strncpy (str, printed, n);
  str[n-1] = '\0';
224 225

  g_free (printed);
226 227 228
  
  return strlen (str);
#endif /* !HAVE_VSNPRINTF */
Owen Taylor's avatar
Owen Taylor committed
229 230
}

231
guint	     
Owen Taylor's avatar
Owen Taylor committed
232 233
g_parse_debug_string  (const gchar *string, 
		       GDebugKey   *keys, 
234
		       guint	    nkeys)
Owen Taylor's avatar
Owen Taylor committed
235 236 237
{
  guint i;
  guint result = 0;
238
  
Owen Taylor's avatar
Owen Taylor committed
239
  g_return_val_if_fail (string != NULL, 0);
240
  
Owen Taylor's avatar
Owen Taylor committed
241 242 243 244 245 246 247 248 249 250 251
  if (!g_strcasecmp (string, "all"))
    {
      for (i=0; i<nkeys; i++)
	result |= keys[i].value;
    }
  else
    {
      gchar *str = g_strdup (string);
      gchar *p = str;
      gchar *q;
      gboolean done = FALSE;
252
      
Owen Taylor's avatar
Owen Taylor committed
253 254 255 256 257 258 259 260
      while (*p && !done)
	{
	  q = strchr (p, ':');
	  if (!q)
	    {
	      q = p + strlen(p);
	      done = TRUE;
	    }
261
	  
Owen Taylor's avatar
Owen Taylor committed
262
	  *q = 0;
263
	  
Owen Taylor's avatar
Owen Taylor committed
264 265 266
	  for (i=0; i<nkeys; i++)
	    if (!g_strcasecmp(keys[i].key, p))
	      result |= keys[i].value;
267
	  
Owen Taylor's avatar
Owen Taylor committed
268 269 270 271 272
	  p = q+1;
	}
      
      g_free (str);
    }
273
  
Owen Taylor's avatar
Owen Taylor committed
274 275 276
  return result;
}

277 278 279 280
gchar*
g_basename (const gchar	   *file_name)
{
  register gchar *base;
281 282 283 284 285 286 287 288 289 290 291
#ifdef G_ENABLE_DEBUG
  static gboolean first_call = TRUE;

  if (first_call)
    {
      g_warning("g_basename is deprecated. Use g_path_get_basename instead.");
      g_warning("Watch out! You have to g_free the string returned by "
		"g_path_get_basename.");
      first_call = FALSE;
    }
#endif /* G_ENABLE_DEBUG */
292 293 294
  
  g_return_val_if_fail (file_name != NULL, NULL);
  
295
  base = strrchr (file_name, G_DIR_SEPARATOR);
296 297
  if (base)
    return base + 1;
298

299
#ifdef G_OS_WIN32
300 301
  if (isalpha (file_name[0]) && file_name[1] == ':')
    return (gchar*) file_name + 2;
302
#endif /* G_OS_WIN32 */
303 304 305 306
  
  return (gchar*) file_name;
}

307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
gchar*
g_path_get_basename (const gchar   *file_name)
{
  register gint base;
  register gint last_nonslash;
  guint len;
  gchar *retval;
 
  g_return_val_if_fail (file_name != NULL, NULL);
  
  if (file_name[0] == '\0')
    /* empty string */
    return g_strdup (".");

  last_nonslash = strlen (file_name) - 1;

  while (last_nonslash >= 0 && file_name [last_nonslash] == G_DIR_SEPARATOR)
    last_nonslash--;

  if (last_nonslash == -1)
    /* string only containing slashes */
    return g_strdup (G_DIR_SEPARATOR_S);

#ifdef G_OS_WIN32
  if (last_nonslash == 1 && isalpha (file_name[0]) && file_name[1] == ':')
    /* string only containing slashes and a drive */
    return g_strdup (G_DIR_SEPARATOR_S);
#endif /* G_OS_WIN32 */

  base = last_nonslash;

  while (base >=0 && file_name [base] != G_DIR_SEPARATOR)
    base--;

#ifdef G_OS_WIN32
  if (base == -1 && isalpha (file_name[0]) && file_name[1] == ':')
    base = 1;
#endif /* G_OS_WIN32 */

  len = last_nonslash - base;
  retval = g_malloc (len + 1);
  memcpy (retval, file_name + base + 1, len);
  retval [len] = '\0';
  return retval;
}

353 354 355 356 357 358 359 360
gboolean
g_path_is_absolute (const gchar *file_name)
{
  g_return_val_if_fail (file_name != NULL, FALSE);
  
  if (file_name[0] == G_DIR_SEPARATOR)
    return TRUE;

361
#ifdef G_OS_WIN32
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
  if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
    return TRUE;
#endif

  return FALSE;
}

gchar*
g_path_skip_root (gchar *file_name)
{
  g_return_val_if_fail (file_name != NULL, NULL);
  
  if (file_name[0] == G_DIR_SEPARATOR)
    return file_name + 1;

377
#ifdef G_OS_WIN32
378 379 380 381 382 383 384
  if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
    return file_name + 3;
#endif

  return NULL;
}

385
gchar*
386
g_path_get_dirname (const gchar	   *file_name)
387 388 389 390 391 392
{
  register gchar *base;
  register guint len;
  
  g_return_val_if_fail (file_name != NULL, NULL);
  
393
  base = strrchr (file_name, G_DIR_SEPARATOR);
394 395
  if (!base)
    return g_strdup (".");
396
  while (base > file_name && *base == G_DIR_SEPARATOR)
397 398
    base--;
  len = (guint) 1 + base - file_name;
Tim Janik's avatar
Tim Janik committed
399
  
400 401 402
  base = g_new (gchar, len + 1);
  g_memmove (base, file_name, len);
  base[len] = 0;
Tim Janik's avatar
Tim Janik committed
403
  
404 405 406
  return base;
}

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
gchar*
g_dirname (const gchar	   *file_name)
{
#ifdef G_ENABLE_DEBUG
  static gboolean first_call = TRUE;

  if (first_call)
    {
      g_warning("g_dirname is deprecated. Use g_path_get_dirname instead.");
      first_call = FALSE;
    }
#endif /* G_ENABLE_DEBUG */

  return g_path_get_dirname (file_name);
}

423
gchar*
424
g_get_current_dir (void)
425
{
426 427
  gchar *buffer = NULL;
  gchar *dir = NULL;
428
  static gulong max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
429 430 431 432 433
  
  /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
   * and, if that wasn't bad enough, hangs in doing so.
   */
#if	defined (sun) && !defined (__SVR4)
434 435
  buffer = g_new (gchar, max_len + 1);
  *buffer = 0;
436
  dir = getwd (buffer);
437
#else	/* !sun */
438
  while (max_len < G_MAXULONG / 2)
439 440 441 442 443 444 445 446 447 448 449
    {
      buffer = g_new (gchar, max_len + 1);
      *buffer = 0;
      dir = getcwd (buffer, max_len);

      if (dir || errno != ERANGE)
	break;

      g_free (buffer);
      max_len *= 2;
    }
450 451
#endif	/* !sun */
  
452
  if (!dir || !*buffer)
453
    {
454 455
      /* hm, should we g_error() out here?
       * this can happen if e.g. "./" has mode \0000
456
       */
457
      buffer[0] = G_DIR_SEPARATOR;
458
      buffer[1] = 0;
459
    }
460 461 462

  dir = g_strdup (buffer);
  g_free (buffer);
463
  
464
  return dir;
465 466
}

467 468 469
gchar*
g_getenv (const gchar *variable)
{
470
#ifndef G_OS_WIN32
471 472 473 474
  g_return_val_if_fail (variable != NULL, NULL);

  return getenv (variable);
#else
475 476 477 478 479 480 481 482 483
  G_LOCK_DEFINE_STATIC (getenv);
  struct env_struct
  {
    gchar *key;
    gchar *value;
  } *env;
  static GArray *environs = NULL;
  gchar *system_env;
  guint length, i;
484
  gchar dummy[2];
485 486

  g_return_val_if_fail (variable != NULL, NULL);
487
  
488 489 490 491 492 493 494
  G_LOCK (getenv);

  if (!environs)
    environs = g_array_new (FALSE, FALSE, sizeof (struct env_struct));

  /* First we try to find the envinronment variable inside the already
   * found ones.
495 496
   */

497
  for (i = 0; i < environs->len; i++)
498
    {
499 500 501 502 503 504 505
      env = &g_array_index (environs, struct env_struct, i);
      if (strcmp (env->key, variable) == 0)
	{
	  g_assert (env->value);
	  G_UNLOCK (getenv);
	  return env->value;
	}
506
    }
507 508 509 510 511

  /* If not found, we ask the system */

  system_env = getenv (variable);
  if (!system_env)
512
    {
513 514
      G_UNLOCK (getenv);
      return NULL;
515
    }
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539

  /* On Windows NT, it is relatively typical that environment variables
   * contain references to other environment variables. Handle that by
   * calling ExpandEnvironmentStrings.
   */

  g_array_set_size (environs, environs->len + 1);

  env = &g_array_index (environs, struct env_struct, environs->len - 1);

  /* First check how much space we need */
  length = ExpandEnvironmentStrings (system_env, dummy, 2);

  /* Then allocate that much, and actualy do the expansion and insert
   * the new found pair into our buffer 
   */

  env->value = g_malloc (length);
  env->key = g_strdup (variable);

  ExpandEnvironmentStrings (system_env, env->value, length);

  G_UNLOCK (getenv);
  return env->value;
540 541 542
#endif
}

543

544
G_LOCK_DEFINE_STATIC (g_utils_global);
545

546 547 548 549 550
static	gchar	*g_tmp_dir = NULL;
static	gchar	*g_user_name = NULL;
static	gchar	*g_real_name = NULL;
static	gchar	*g_home_dir = NULL;

551
/* HOLDS: g_utils_global_lock */
552 553 554 555 556
static void
g_get_any_init (void)
{
  if (!g_tmp_dir)
    {
557
      g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
Tim Janik's avatar
Tim Janik committed
558
      if (!g_tmp_dir)
559
	g_tmp_dir = g_strdup (g_getenv ("TMP"));
560
      if (!g_tmp_dir)
561 562
	g_tmp_dir = g_strdup (g_getenv ("TEMP"));
      
563 564 565 566 567 568 569 570 571 572
#ifdef P_tmpdir
      if (!g_tmp_dir)
	{
	  int k;
	  g_tmp_dir = g_strdup (P_tmpdir);
	  k = strlen (g_tmp_dir);
	  if (g_tmp_dir[k-1] == G_DIR_SEPARATOR)
	    g_tmp_dir[k-1] = '\0';
	}
#endif
573
      
574
      if (!g_tmp_dir)
575
	{
576
#ifndef G_OS_WIN32
577
	  g_tmp_dir = g_strdup ("/tmp");
578
#else /* G_OS_WIN32 */
579
	  g_tmp_dir = g_strdup ("C:\\");
580
#endif /* G_OS_WIN32 */
581
	}
582
      
583 584
      if (!g_home_dir)
	g_home_dir = g_strdup (g_getenv ("HOME"));
585
      
586
#ifdef G_OS_WIN32
587
      if (!g_home_dir)
588
	{
589 590 591
	  /* The official way to specify a home directory on NT is
	   * the HOMEDRIVE and HOMEPATH environment variables.
	   *
592
	   * This is inside #ifdef G_OS_WIN32 because with the cygwin dll,
593 594 595 596 597 598 599 600 601 602 603 604 605 606
	   * HOME should be a POSIX style pathname.
	   */
	  
	  if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
	    {
	      gchar *homedrive, *homepath;
	      
	      homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
	      homepath = g_strdup (g_getenv ("HOMEPATH"));
	      
	      g_home_dir = g_strconcat (homedrive, homepath, NULL);
	      g_free (homedrive);
	      g_free (homepath);
	    }
607
	}
608
#endif /* G_OS_WIN32 */
609
      
610
#ifdef HAVE_PWD_H
611
      {
612
	struct passwd *pw = NULL;
613
	gpointer buffer = NULL;
614
	
615
#  ifdef HAVE_GETPWUID_R
616
        struct passwd pwd;
617 618 619 620
#    ifdef _SC_GETPW_R_SIZE_MAX  
	/* This reurns the maximum length */
        guint bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
#    else /* _SC_GETPW_R_SIZE_MAX */
621
        guint bufsize = 64;
622
#    endif /* _SC_GETPW_R_SIZE_MAX */
623
        gint error;
624 625
	
        do
626 627 628
          {
            g_free (buffer);
            buffer = g_malloc (bufsize);
629
	    errno = 0;
630
	    
631
#    ifdef HAVE_GETPWUID_R_POSIX
632
	    error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
633
            error = error < 0 ? errno : error;
634
#    else /* !HAVE_GETPWUID_R_POSIX */
635 636 637 638
#      ifdef _AIX
	    error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
	    pw = error == 0 ? &pwd : NULL;
#      else /* !_AIX */
639 640
            pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
            error = pw ? 0 : errno;
641
#      endif /* !_AIX */            
642
#    endif /* !HAVE_GETPWUID_R_POSIX */
643 644
	    
	    if (!pw)
645
	      {
646 647 648 649 650 651 652
		/* we bail out prematurely if the user id can't be found
		 * (should be pretty rare case actually), or if the buffer
		 * should be sufficiently big and lookups are still not
		 * successfull.
		 */
		if (error == 0 || error == ENOENT)
		  {
Tim Janik's avatar
Tim Janik committed
653 654
		    g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
			       (gulong) getuid ());
655 656 657 658 659 660 661 662 663 664
		    break;
		  }
		if (bufsize > 32 * 1024)
		  {
		    g_warning ("getpwuid_r(): failed due to: %s.",
			       g_strerror (error));
		    break;
		  }
		
		bufsize *= 2;
665
	      }
666 667
	  }
	while (!pw);
668
#  endif /* !HAVE_GETPWUID_R */
669
	
670 671 672 673 674 675
	if (!pw)
	  {
	    setpwent ();
	    pw = getpwuid (getuid ());
	    endpwent ();
	  }
676 677 678 679 680 681 682 683 684
	if (pw)
	  {
	    g_user_name = g_strdup (pw->pw_name);
	    g_real_name = g_strdup (pw->pw_gecos);
	    if (!g_home_dir)
	      g_home_dir = g_strdup (pw->pw_dir);
	  }
	g_free (buffer);
      }
685
      
686
#else /* !HAVE_PWD_H */
687
      
688
#  ifdef G_OS_WIN32
689 690
      {
	guint len = 17;
691
	gchar buffer[17];
692
	
Tor Lillqvist's avatar
Tor Lillqvist committed
693
	if (GetUserName ((LPTSTR) buffer, (LPDWORD) &len))
694
	  {
695 696
	    g_user_name = g_strdup (buffer);
	    g_real_name = g_strdup (buffer);
697 698
	  }
      }
699
#  endif /* G_OS_WIN32 */
700
      
701
#endif /* !HAVE_PWD_H */
702
      
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
703 704 705 706
#ifdef __EMX__
      /* change '\\' in %HOME% to '/' */
      g_strdelimit (g_home_dir, "\\",'/');
#endif
707 708 709 710
      if (!g_user_name)
	g_user_name = g_strdup ("somebody");
      if (!g_real_name)
	g_real_name = g_strdup ("Unknown");
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
      else
	{
	  gchar *p;

	  for (p = g_real_name; *p; p++)
	    if (*p == ',')
	      {
		*p = 0;
		p = g_strdup (g_real_name);
		g_free (g_real_name);
		g_real_name = p;
		break;
	      }
	}
    }
726 727 728 729 730
}

gchar*
g_get_user_name (void)
{
731
  G_LOCK (g_utils_global);
732 733
  if (!g_tmp_dir)
    g_get_any_init ();
734
  G_UNLOCK (g_utils_global);
735 736 737 738 739 740 741
  
  return g_user_name;
}

gchar*
g_get_real_name (void)
{
742
  G_LOCK (g_utils_global);
743 744
  if (!g_tmp_dir)
    g_get_any_init ();
745
  G_UNLOCK (g_utils_global);
746
 
747 748 749
  return g_real_name;
}

750 751 752 753 754 755
/* Return the home directory of the user. If there is a HOME
 * environment variable, its value is returned, otherwise use some
 * system-dependent way of finding it out. If no home directory can be
 * deduced, return NULL.
 */

756 757 758
gchar*
g_get_home_dir (void)
{
759
  G_LOCK (g_utils_global);
760 761
  if (!g_tmp_dir)
    g_get_any_init ();
762
  G_UNLOCK (g_utils_global);
763 764 765 766
  
  return g_home_dir;
}

767 768 769 770 771 772 773
/* Return a directory to be used to store temporary files. This is the
 * value of the TMPDIR, TMP or TEMP environment variables (they are
 * checked in that order). If none of those exist, use P_tmpdir from
 * stdio.h.  If that isn't defined, return "/tmp" on POSIXly systems,
 * and C:\ on Windows.
 */

774 775 776
gchar*
g_get_tmp_dir (void)
{
777
  G_LOCK (g_utils_global);
778 779
  if (!g_tmp_dir)
    g_get_any_init ();
780
  G_UNLOCK (g_utils_global);
781 782 783 784 785 786 787 788 789
  
  return g_tmp_dir;
}

static gchar *g_prgname = NULL;

gchar*
g_get_prgname (void)
{
790 791
  gchar* retval;

792
  G_LOCK (g_utils_global);
793
  retval = g_prgname;
794
  G_UNLOCK (g_utils_global);
795 796

  return retval;
797 798 799 800 801
}

void
g_set_prgname (const gchar *prgname)
{
802 803
  gchar *c;
    
804
  G_LOCK (g_utils_global);
805
  c = g_prgname;
806 807
  g_prgname = g_strdup (prgname);
  g_free (c);
808
  G_UNLOCK (g_utils_global);
809 810
}

Owen Taylor's avatar
Owen Taylor committed
811
guint
812
g_direct_hash (gconstpointer v)
Owen Taylor's avatar
Owen Taylor committed
813
{
814
  return GPOINTER_TO_UINT (v);
Owen Taylor's avatar
Owen Taylor committed
815 816
}

817
gint
818 819
g_direct_equal (gconstpointer v1,
		gconstpointer v2)
820
{
821
  return v1 == v2;
822 823 824
}

gint
825 826
g_int_equal (gconstpointer v1,
	     gconstpointer v2)
827
{
828
  return *((const gint*) v1) == *((const gint*) v2);
829 830 831 832 833 834 835
}

guint
g_int_hash (gconstpointer v)
{
  return *(const gint*) v;
}
836

837 838 839 840 841 842 843 844
/**
 * g_get_codeset:
 * 
 * Get the codeset for the current locale.
 * 
 * Return value: a newly allocated string containing the name
 * of the codeset. This string must be freed with g_free().
 **/
845
gchar *
846
g_get_codeset (void)
847 848 849 850 851
{
#ifdef HAVE_CODESET  
  char *result = nl_langinfo (CODESET);
  return g_strdup (result);
#else
Tor Lillqvist's avatar
Tor Lillqvist committed
852
#ifndef G_OS_WIN32
853 854 855
  /* FIXME: Do something more intelligent based on setlocale (LC_CTYPE, NULL)
   */
  return g_strdup ("ISO-8859-1");
Tor Lillqvist's avatar
Tor Lillqvist committed
856 857 858 859 860 861
#else
  /* On Win32 we always use UTF-8. At least in GDK. SO should we
   * therefore return that?
   */
  return g_strdup ("UTF-8");
#endif
862 863
#endif
}