glib/libglib/src/gfileutils.c
branchRCL_3
changeset 57 2efc27d87e1c
parent 0 e4d67989cc36
child 13 ef48f5dc1b7f
equal deleted inserted replaced
56:acd3cd4aaceb 57:2efc27d87e1c
       
     1 /* gfileutils.c - File utility functions
       
     2  *
       
     3  *  Copyright 2000 Red Hat, Inc.
       
     4  * Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
     5  *
       
     6  * GLib is free software; you can redistribute it and/or modify it
       
     7  * under the terms of the GNU Lesser General Public License as
       
     8  * published by the Free Software Foundation; either version 2 of the
       
     9  * License, or (at your option) any later version.
       
    10  *
       
    11  * GLib is distributed in the hope that it will be useful,
       
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    14  * Lesser General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU Lesser General Public
       
    17  * License along with GLib; see the file COPYING.LIB.  If not,
       
    18  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    19  *   Boston, MA 02111-1307, USA.
       
    20  */
       
    21 
       
    22 #include "config.h"
       
    23 
       
    24 #include "glib.h"
       
    25 
       
    26 #include <sys/stat.h>
       
    27 #ifdef HAVE_UNISTD_H
       
    28 #include <unistd.h>
       
    29 #endif
       
    30 #include <stdio.h>
       
    31 #include <stdlib.h>
       
    32 #include <stdarg.h>
       
    33 #include <string.h>
       
    34 #include <errno.h>
       
    35 #include <sys/types.h>
       
    36 #include <sys/stat.h>
       
    37 #include <fcntl.h>
       
    38 #include <stdlib.h>
       
    39 
       
    40 #ifdef G_OS_WIN32
       
    41 #include <windows.h>
       
    42 #include <io.h>
       
    43 #endif /* G_OS_WIN32 */
       
    44 
       
    45 #ifndef S_ISLNK
       
    46 #define S_ISLNK(x) 0
       
    47 #endif
       
    48 
       
    49 #ifndef O_BINARY
       
    50 #define O_BINARY 0
       
    51 #endif
       
    52 
       
    53 #include "gstdio.h"
       
    54 #include "glibintl.h"
       
    55 
       
    56 #include "galias.h"
       
    57 
       
    58 #ifdef __SYMBIAN32__
       
    59 #include <glib_wsd.h>
       
    60 #endif /* __SYMBIAN32__ */
       
    61 
       
    62 
       
    63 /**
       
    64  * g_mkdir_with_parents:
       
    65  * @pathname: a pathname in the GLib file name encoding
       
    66  * @mode: permissions to use for newly created directories
       
    67  *
       
    68  * Create a directory if it doesn't already exist. Create intermediate
       
    69  * parent directories as needed, too.
       
    70  *
       
    71  * Returns: 0 if the directory already exists, or was successfully
       
    72  * created. Returns -1 if an error occurred, with errno set.
       
    73  *
       
    74  * Since: 2.8
       
    75  */
       
    76 EXPORT_C int
       
    77 g_mkdir_with_parents (const gchar *pathname,
       
    78 		      int          mode)
       
    79 {
       
    80   gchar *fn, *p;
       
    81 
       
    82   if (pathname == NULL || *pathname == '\0')
       
    83     {
       
    84       errno = EINVAL;
       
    85       return -1;
       
    86     }
       
    87 
       
    88   fn = g_strdup (pathname);
       
    89 
       
    90   if (g_path_is_absolute (fn))
       
    91     p = (gchar *) g_path_skip_root (fn);
       
    92   else
       
    93     p = fn;
       
    94 
       
    95   do
       
    96     {
       
    97       while (*p && !G_IS_DIR_SEPARATOR (*p))
       
    98 	p++;
       
    99       
       
   100       if (!*p)
       
   101 	p = NULL;
       
   102       else
       
   103 	*p = '\0';
       
   104       
       
   105       if (!g_file_test (fn, G_FILE_TEST_EXISTS))
       
   106 	{
       
   107 	  if (g_mkdir (fn, mode) == -1)
       
   108 	    {
       
   109 	      int errno_save = errno;
       
   110 	      g_free (fn);
       
   111 	      errno = errno_save;
       
   112 	      return -1;
       
   113 	    }
       
   114 	}
       
   115       else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
       
   116 	{
       
   117 	  g_free (fn);
       
   118 	  errno = ENOTDIR;
       
   119 	  return -1;
       
   120 	}
       
   121       if (p)
       
   122 	{
       
   123 	  *p++ = G_DIR_SEPARATOR;
       
   124 	  while (*p && G_IS_DIR_SEPARATOR (*p))
       
   125 	    p++;
       
   126 	}
       
   127     }
       
   128   while (p);
       
   129 
       
   130   g_free (fn);
       
   131 
       
   132   return 0;
       
   133 }
       
   134 
       
   135 /**
       
   136  * g_file_test:
       
   137  * @filename: a filename to test in the GLib file name encoding
       
   138  * @test: bitfield of #GFileTest flags
       
   139  * 
       
   140  * Returns %TRUE if any of the tests in the bitfield @test are
       
   141  * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS | 
       
   142  * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; 
       
   143  * the check whether it's a directory doesn't matter since the existence 
       
   144  * test is %TRUE. With the current set of available tests, there's no point
       
   145  * passing in more than one test at a time.
       
   146  * 
       
   147  * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
       
   148  * so for a symbolic link to a regular file g_file_test() will return
       
   149  * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
       
   150  *
       
   151  * Note, that for a dangling symbolic link g_file_test() will return
       
   152  * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
       
   153  *
       
   154  * You should never use g_file_test() to test whether it is safe
       
   155  * to perform an operation, because there is always the possibility
       
   156  * of the condition changing before you actually perform the operation.
       
   157  * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
       
   158  * to know whether it is is safe to write to a file without being
       
   159  * tricked into writing into a different location. It doesn't work!
       
   160  *
       
   161  * <informalexample><programlisting>
       
   162  * /&ast; DON'T DO THIS &ast;/
       
   163  *  if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) {
       
   164  *    fd = g_open (filename, O_WRONLY);
       
   165  *    /&ast; write to fd &ast;/
       
   166  *  }
       
   167  * </programlisting></informalexample>
       
   168  *
       
   169  * Another thing to note is that %G_FILE_TEST_EXISTS and
       
   170  * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
       
   171  * system call. This usually doesn't matter, but if your program
       
   172  * is setuid or setgid it means that these tests will give you
       
   173  * the answer for the real user ID and group ID, rather than the
       
   174  * effective user ID and group ID.
       
   175  *
       
   176  * On Windows, there are no symlinks, so testing for
       
   177  * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for
       
   178  * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and
       
   179  * its name indicates that it is executable, checking for well-known
       
   180  * extensions and those listed in the %PATHEXT environment variable.
       
   181  *
       
   182  * Return value: whether a test was %TRUE
       
   183  **/
       
   184 EXPORT_C gboolean
       
   185 g_file_test (const gchar *filename,
       
   186              GFileTest    test)
       
   187 {
       
   188 #ifdef G_OS_WIN32
       
   189 /* stuff missing in std vc6 api */
       
   190 #  ifndef INVALID_FILE_ATTRIBUTES
       
   191 #    define INVALID_FILE_ATTRIBUTES -1
       
   192 #  endif
       
   193 #  ifndef FILE_ATTRIBUTE_DEVICE
       
   194 #    define FILE_ATTRIBUTE_DEVICE 64
       
   195 #  endif
       
   196   int attributes;
       
   197 
       
   198   if (G_WIN32_HAVE_WIDECHAR_API ())
       
   199     {
       
   200       wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
       
   201 
       
   202       if (wfilename == NULL)
       
   203 	return FALSE;
       
   204 
       
   205       attributes = GetFileAttributesW (wfilename);
       
   206 
       
   207       g_free (wfilename);
       
   208     }
       
   209   else
       
   210     {
       
   211       gchar *cpfilename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
       
   212 
       
   213       if (cpfilename == NULL)
       
   214 	return FALSE;
       
   215       
       
   216       attributes = GetFileAttributesA (cpfilename);
       
   217       
       
   218       g_free (cpfilename);
       
   219     }
       
   220 
       
   221   if (attributes == INVALID_FILE_ATTRIBUTES)
       
   222     return FALSE;
       
   223 
       
   224   if (test & G_FILE_TEST_EXISTS)
       
   225     return TRUE;
       
   226       
       
   227   if (test & G_FILE_TEST_IS_REGULAR)
       
   228     return (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0;
       
   229 
       
   230   if (test & G_FILE_TEST_IS_DIR)
       
   231     return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
       
   232 
       
   233   if (test & G_FILE_TEST_IS_EXECUTABLE)
       
   234     {
       
   235       const gchar *lastdot = strrchr (filename, '.');
       
   236       const gchar *pathext = NULL, *p;
       
   237       int extlen;
       
   238 
       
   239       if (lastdot == NULL)
       
   240 	return FALSE;
       
   241 
       
   242       if (stricmp (lastdot, ".exe") == 0 ||
       
   243 	  stricmp (lastdot, ".cmd") == 0 ||
       
   244 	  stricmp (lastdot, ".bat") == 0 ||
       
   245 	  stricmp (lastdot, ".com") == 0)
       
   246 	return TRUE;
       
   247 
       
   248       /* Check if it is one of the types listed in %PATHEXT% */
       
   249 
       
   250       pathext = g_getenv ("PATHEXT");
       
   251       if (pathext == NULL)
       
   252 	return FALSE;
       
   253 
       
   254       pathext = g_utf8_casefold (pathext, -1);
       
   255 
       
   256       lastdot = g_utf8_casefold (lastdot, -1);
       
   257       extlen = strlen (lastdot);
       
   258 
       
   259       p = pathext;
       
   260       while (TRUE)
       
   261 	{
       
   262 	  const gchar *q = strchr (p, ';');
       
   263 	  if (q == NULL)
       
   264 	    q = p + strlen (p);
       
   265 	  if (extlen == q - p &&
       
   266 	      memcmp (lastdot, p, extlen) == 0)
       
   267 	    {
       
   268 	      g_free ((gchar *) pathext);
       
   269 	      g_free ((gchar *) lastdot);
       
   270 	      return TRUE;
       
   271 	    }
       
   272 	  if (*q)
       
   273 	    p = q + 1;
       
   274 	  else
       
   275 	    break;
       
   276 	}
       
   277 
       
   278       g_free ((gchar *) pathext);
       
   279       g_free ((gchar *) lastdot);
       
   280       return FALSE;
       
   281     }
       
   282 
       
   283   return FALSE;
       
   284 #else
       
   285   if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
       
   286     return TRUE;
       
   287   
       
   288   if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
       
   289     {
       
   290       #ifndef __SYMBIAN32__
       
   291       if (getuid () != 0)
       
   292       #endif /* __SYMBIAN32__ */
       
   293 		return TRUE;
       
   294 
       
   295       /* For root, on some POSIX systems, access (filename, X_OK)
       
   296        * will succeed even if no executable bits are set on the
       
   297        * file. We fall through to a stat test to avoid that.
       
   298        */
       
   299     }
       
   300   else
       
   301     test &= ~G_FILE_TEST_IS_EXECUTABLE;
       
   302 
       
   303   if (test & G_FILE_TEST_IS_SYMLINK)
       
   304     {
       
   305       struct stat s;
       
   306 
       
   307       if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
       
   308         return TRUE;
       
   309     }
       
   310   
       
   311   if (test & (G_FILE_TEST_IS_REGULAR |
       
   312 	      G_FILE_TEST_IS_DIR |
       
   313 	      G_FILE_TEST_IS_EXECUTABLE))
       
   314     {
       
   315       struct stat s;
       
   316       
       
   317       if (stat (filename, &s) == 0)
       
   318 	{
       
   319 	  if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
       
   320 	    return TRUE;
       
   321 	  
       
   322 	  if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
       
   323 	    return TRUE;
       
   324 
       
   325 	  /* The extra test for root when access (file, X_OK) succeeds.
       
   326 	   */
       
   327 	  if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
       
   328 	      ((s.st_mode & S_IXOTH) ||
       
   329 	       (s.st_mode & S_IXUSR) ||
       
   330 	       (s.st_mode & S_IXGRP)))
       
   331 	    return TRUE;
       
   332 	}
       
   333     }
       
   334 
       
   335   return FALSE;
       
   336 #endif
       
   337 }
       
   338 
       
   339 #ifdef G_OS_WIN32
       
   340 
       
   341 #undef g_file_test
       
   342 
       
   343 /* Binary compatibility version. Not for newly compiled code. */
       
   344 
       
   345 EXPORT_C gboolean
       
   346 g_file_test (const gchar *filename,
       
   347              GFileTest    test)
       
   348 {
       
   349   gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
       
   350   gboolean retval;
       
   351 
       
   352   if (utf8_filename == NULL)
       
   353     return FALSE;
       
   354 
       
   355   retval = g_file_test_utf8 (utf8_filename, test);
       
   356 
       
   357   g_free (utf8_filename);
       
   358 
       
   359   return retval;
       
   360 }
       
   361 
       
   362 #endif
       
   363 
       
   364 #if EMULATOR
       
   365 
       
   366 PLS(q,g_file_error_quark ,GQuark)
       
   367 #define q (*FUNCTION_NAME(q,g_file_error_quark )())
       
   368 
       
   369 #endif /* EMULATOR */
       
   370 
       
   371 EXPORT_C GQuark
       
   372 g_file_error_quark (void)
       
   373 {
       
   374   #if !(EMULATOR)
       
   375   static GQuark q = 0;
       
   376   #endif /* EMULATOR */
       
   377   
       
   378   if (q == 0)
       
   379     q = g_quark_from_static_string ("g-file-error-quark");
       
   380 
       
   381   return q;
       
   382 }
       
   383 #if EMULATOR
       
   384 #undef q
       
   385 #endif /* EMULATOR */
       
   386 
       
   387 /**
       
   388  * g_file_error_from_errno:
       
   389  * @err_no: an "errno" value
       
   390  * 
       
   391  * Gets a #GFileError constant based on the passed-in @errno.
       
   392  * For example, if you pass in %EEXIST this function returns
       
   393  * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably
       
   394  * assume that all #GFileError values will exist.
       
   395  *
       
   396  * Normally a #GFileError value goes into a #GError returned
       
   397  * from a function that manipulates files. So you would use
       
   398  * g_file_error_from_errno() when constructing a #GError.
       
   399  * 
       
   400  * Return value: #GFileError corresponding to the given @errno
       
   401  **/
       
   402 EXPORT_C GFileError
       
   403 g_file_error_from_errno (gint err_no)
       
   404 {
       
   405   switch (err_no)
       
   406     {
       
   407 #ifdef EEXIST
       
   408     case EEXIST:
       
   409       return G_FILE_ERROR_EXIST;
       
   410       break;
       
   411 #endif
       
   412 
       
   413 #ifdef EISDIR
       
   414     case EISDIR:
       
   415       return G_FILE_ERROR_ISDIR;
       
   416       break;
       
   417 #endif
       
   418 
       
   419 #ifdef EACCES
       
   420     case EACCES:
       
   421       return G_FILE_ERROR_ACCES;
       
   422       break;
       
   423 #endif
       
   424 
       
   425 #ifdef ENAMETOOLONG
       
   426     case ENAMETOOLONG:
       
   427       return G_FILE_ERROR_NAMETOOLONG;
       
   428       break;
       
   429 #endif
       
   430 
       
   431 #ifdef ENOENT
       
   432     case ENOENT:
       
   433       return G_FILE_ERROR_NOENT;
       
   434       break;
       
   435 #endif
       
   436 
       
   437 #ifdef ENOTDIR
       
   438     case ENOTDIR:
       
   439       return G_FILE_ERROR_NOTDIR;
       
   440       break;
       
   441 #endif
       
   442 
       
   443 #ifdef ENXIO
       
   444     case ENXIO:
       
   445       return G_FILE_ERROR_NXIO;
       
   446       break;
       
   447 #endif
       
   448 
       
   449 #ifdef ENODEV
       
   450     case ENODEV:
       
   451       return G_FILE_ERROR_NODEV;
       
   452       break;
       
   453 #endif
       
   454 
       
   455 #ifdef EROFS
       
   456     case EROFS:
       
   457       return G_FILE_ERROR_ROFS;
       
   458       break;
       
   459 #endif
       
   460 
       
   461 #ifdef ETXTBSY
       
   462     case ETXTBSY:
       
   463       return G_FILE_ERROR_TXTBSY;
       
   464       break;
       
   465 #endif
       
   466 
       
   467 #ifdef EFAULT
       
   468     case EFAULT:
       
   469       return G_FILE_ERROR_FAULT;
       
   470       break;
       
   471 #endif
       
   472 
       
   473 #ifdef ELOOP
       
   474     case ELOOP:
       
   475       return G_FILE_ERROR_LOOP;
       
   476       break;
       
   477 #endif
       
   478 
       
   479 #ifdef ENOSPC
       
   480     case ENOSPC:
       
   481       return G_FILE_ERROR_NOSPC;
       
   482       break;
       
   483 #endif
       
   484 
       
   485 #ifdef ENOMEM
       
   486     case ENOMEM:
       
   487       return G_FILE_ERROR_NOMEM;
       
   488       break;
       
   489 #endif
       
   490 
       
   491 #ifdef EMFILE
       
   492     case EMFILE:
       
   493       return G_FILE_ERROR_MFILE;
       
   494       break;
       
   495 #endif
       
   496 
       
   497 #ifdef ENFILE
       
   498     case ENFILE:
       
   499       return G_FILE_ERROR_NFILE;
       
   500       break;
       
   501 #endif
       
   502 
       
   503 #ifdef EBADF
       
   504     case EBADF:
       
   505       return G_FILE_ERROR_BADF;
       
   506       break;
       
   507 #endif
       
   508 
       
   509 #ifdef EINVAL
       
   510     case EINVAL:
       
   511       return G_FILE_ERROR_INVAL;
       
   512       break;
       
   513 #endif
       
   514 
       
   515 #ifdef EPIPE
       
   516     case EPIPE:
       
   517       return G_FILE_ERROR_PIPE;
       
   518       break;
       
   519 #endif
       
   520 
       
   521 #ifdef EAGAIN
       
   522     case EAGAIN:
       
   523       return G_FILE_ERROR_AGAIN;
       
   524       break;
       
   525 #endif
       
   526 
       
   527 #ifdef EINTR
       
   528     case EINTR:
       
   529       return G_FILE_ERROR_INTR;
       
   530       break;
       
   531 #endif
       
   532 
       
   533 #ifdef EIO
       
   534     case EIO:
       
   535       return G_FILE_ERROR_IO;
       
   536       break;
       
   537 #endif
       
   538 
       
   539 #ifdef EPERM
       
   540     case EPERM:
       
   541       return G_FILE_ERROR_PERM;
       
   542       break;
       
   543 #endif
       
   544 
       
   545 #ifdef ENOSYS
       
   546     case ENOSYS:
       
   547       return G_FILE_ERROR_NOSYS;
       
   548       break;
       
   549 #endif
       
   550 
       
   551     default:
       
   552       return G_FILE_ERROR_FAILED;
       
   553       break;
       
   554     }
       
   555 }
       
   556 
       
   557 static gboolean
       
   558 get_contents_stdio (const gchar *display_filename,
       
   559                     FILE        *f,
       
   560                     gchar      **contents,
       
   561                     gsize       *length,
       
   562                     GError     **error)
       
   563 {
       
   564   gchar buf[4096];
       
   565   size_t bytes;
       
   566   gchar *str = NULL;
       
   567   size_t total_bytes = 0;
       
   568   size_t total_allocated = 0;
       
   569   gchar *tmp;
       
   570 
       
   571   g_assert (f != NULL);
       
   572 
       
   573   while (!feof (f))
       
   574     {
       
   575       gint save_errno;
       
   576 
       
   577       bytes = fread (buf, 1, sizeof (buf), f);
       
   578       save_errno = errno;
       
   579 
       
   580       while ((total_bytes + bytes + 1) > total_allocated)
       
   581         {
       
   582           if (str)
       
   583             total_allocated *= 2;
       
   584           else
       
   585             total_allocated = MIN (bytes + 1, sizeof (buf));
       
   586 
       
   587           tmp = g_try_realloc (str, total_allocated);
       
   588 
       
   589           if (tmp == NULL)
       
   590             {
       
   591               g_set_error (error,
       
   592                            G_FILE_ERROR,
       
   593                            G_FILE_ERROR_NOMEM,
       
   594                            _("Could not allocate %lu bytes to read file \"%s\""),
       
   595                            (gulong) total_allocated,
       
   596 			   display_filename);
       
   597 
       
   598               goto error;
       
   599             }
       
   600 
       
   601 	  str = tmp;
       
   602         }
       
   603 
       
   604       if (ferror (f))
       
   605         {
       
   606           g_set_error (error,
       
   607                        G_FILE_ERROR,
       
   608                        g_file_error_from_errno (save_errno),
       
   609                        _("Error reading file '%s': %s"),
       
   610                        display_filename,
       
   611 		       g_strerror (save_errno));
       
   612 
       
   613           goto error;
       
   614         }
       
   615 
       
   616       memcpy (str + total_bytes, buf, bytes);
       
   617       total_bytes += bytes;
       
   618     }
       
   619 
       
   620   fclose (f);
       
   621 
       
   622   if (total_allocated == 0)
       
   623     str = g_new (gchar, 1);
       
   624 
       
   625   str[total_bytes] = '\0';
       
   626 
       
   627   if (length)
       
   628     *length = total_bytes;
       
   629 
       
   630   *contents = str;
       
   631 
       
   632   return TRUE;
       
   633 
       
   634  error:
       
   635 
       
   636   g_free (str);
       
   637   fclose (f);
       
   638 
       
   639   return FALSE;
       
   640 }
       
   641 
       
   642 #ifndef G_OS_WIN32
       
   643 
       
   644 static gboolean
       
   645 get_contents_regfile (const gchar *display_filename,
       
   646                       struct stat *stat_buf,
       
   647                       gint         fd,
       
   648                       gchar      **contents,
       
   649                       gsize       *length,
       
   650                       GError     **error)
       
   651 {
       
   652   gchar *buf;
       
   653   size_t bytes_read;
       
   654   size_t size;
       
   655   size_t alloc_size;
       
   656   
       
   657   size = stat_buf->st_size;
       
   658 
       
   659   alloc_size = size + 1;
       
   660   buf = g_try_malloc (alloc_size);
       
   661 
       
   662   if (buf == NULL)
       
   663     {
       
   664       g_set_error (error,
       
   665                    G_FILE_ERROR,
       
   666                    G_FILE_ERROR_NOMEM,
       
   667                    _("Could not allocate %lu bytes to read file \"%s\""),
       
   668                    (gulong) alloc_size, 
       
   669 		   display_filename);
       
   670 
       
   671       goto error;
       
   672     }
       
   673   
       
   674   bytes_read = 0;
       
   675   while (bytes_read < size)
       
   676     {
       
   677       gssize rc;
       
   678           
       
   679       rc = read (fd, buf + bytes_read, size - bytes_read);
       
   680 
       
   681       if (rc < 0)
       
   682         {
       
   683           if (errno != EINTR) 
       
   684             {
       
   685 	      int save_errno = errno;
       
   686 
       
   687               g_free (buf);
       
   688               g_set_error (error,
       
   689                            G_FILE_ERROR,
       
   690                            g_file_error_from_errno (save_errno),
       
   691                            _("Failed to read from file '%s': %s"),
       
   692                            display_filename, 
       
   693 			   g_strerror (save_errno));
       
   694 
       
   695 	      goto error;
       
   696             }
       
   697         }
       
   698       else if (rc == 0)
       
   699         break;
       
   700       else
       
   701         bytes_read += rc;
       
   702     }
       
   703       
       
   704   buf[bytes_read] = '\0';
       
   705 
       
   706   if (length)
       
   707     *length = bytes_read;
       
   708   
       
   709   *contents = buf;
       
   710 
       
   711   close (fd);
       
   712 
       
   713   return TRUE;
       
   714 
       
   715  error:
       
   716 
       
   717   close (fd);
       
   718   
       
   719   return FALSE;
       
   720 }
       
   721 
       
   722 static gboolean
       
   723 get_contents_posix (const gchar *filename,
       
   724                     gchar      **contents,
       
   725                     gsize       *length,
       
   726                     GError     **error)
       
   727 {
       
   728   struct stat stat_buf;
       
   729   gint fd;
       
   730   gchar *display_filename = g_filename_display_name (filename);
       
   731 
       
   732   /* O_BINARY useful on Cygwin */
       
   733   fd = open (filename, O_RDONLY|O_BINARY);
       
   734 
       
   735   if (fd < 0)
       
   736     {
       
   737       int save_errno = errno;
       
   738 
       
   739       g_set_error (error,
       
   740                    G_FILE_ERROR,
       
   741                    g_file_error_from_errno (save_errno),
       
   742                    _("Failed to open file '%s': %s"),
       
   743                    display_filename, 
       
   744 		   g_strerror (save_errno));
       
   745       g_free (display_filename);
       
   746 
       
   747       return FALSE;
       
   748     }
       
   749 
       
   750   /* I don't think this will ever fail, aside from ENOMEM, but. */
       
   751   if (fstat (fd, &stat_buf) < 0)
       
   752     {
       
   753       int save_errno = errno;
       
   754 
       
   755       close (fd);
       
   756       g_set_error (error,
       
   757                    G_FILE_ERROR,
       
   758                    g_file_error_from_errno (save_errno),
       
   759                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
       
   760                    display_filename, 
       
   761 		   g_strerror (save_errno));
       
   762       g_free (display_filename);
       
   763 
       
   764       return FALSE;
       
   765     }
       
   766 
       
   767   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
       
   768     {
       
   769       gboolean retval = get_contents_regfile (display_filename,
       
   770 					      &stat_buf,
       
   771 					      fd,
       
   772 					      contents,
       
   773 					      length,
       
   774 					      error);
       
   775       g_free (display_filename);
       
   776 
       
   777       return retval;
       
   778     }
       
   779   else
       
   780     {
       
   781       FILE *f;
       
   782       gboolean retval;
       
   783 
       
   784       f = fdopen (fd, "r");
       
   785       
       
   786       if (f == NULL)
       
   787         {
       
   788 	  int save_errno = errno;
       
   789 
       
   790           g_set_error (error,
       
   791                        G_FILE_ERROR,
       
   792                        g_file_error_from_errno (save_errno),
       
   793                        _("Failed to open file '%s': fdopen() failed: %s"),
       
   794                        display_filename, 
       
   795 		       g_strerror (save_errno));
       
   796           g_free (display_filename);
       
   797 
       
   798           return FALSE;
       
   799         }
       
   800   
       
   801       retval = get_contents_stdio (display_filename, f, contents, length, error);
       
   802       g_free (display_filename);
       
   803 
       
   804       return retval;
       
   805     }
       
   806 }
       
   807 
       
   808 #else  /* G_OS_WIN32 */
       
   809 
       
   810 static gboolean
       
   811 get_contents_win32 (const gchar *filename,
       
   812 		    gchar      **contents,
       
   813 		    gsize       *length,
       
   814 		    GError     **error)
       
   815 {
       
   816   FILE *f;
       
   817   gboolean retval;
       
   818   gchar *display_filename = g_filename_display_name (filename);
       
   819   int save_errno;
       
   820   
       
   821   f = g_fopen (filename, "rb");
       
   822   save_errno = errno;
       
   823 
       
   824   if (f == NULL)
       
   825     {
       
   826       g_set_error (error,
       
   827                    G_FILE_ERROR,
       
   828                    g_file_error_from_errno (save_errno),
       
   829                    _("Failed to open file '%s': %s"),
       
   830                    display_filename,
       
   831 		   g_strerror (save_errno));
       
   832       g_free (display_filename);
       
   833 
       
   834       return FALSE;
       
   835     }
       
   836   
       
   837   retval = get_contents_stdio (display_filename, f, contents, length, error);
       
   838   g_free (display_filename);
       
   839 
       
   840   return retval;
       
   841 }
       
   842 
       
   843 #endif
       
   844 
       
   845 /**
       
   846  * g_file_get_contents:
       
   847  * @filename: name of a file to read contents from, in the GLib file name encoding
       
   848  * @contents: location to store an allocated string
       
   849  * @length: location to store length in bytes of the contents, or %NULL
       
   850  * @error: return location for a #GError, or %NULL
       
   851  * 
       
   852  * Reads an entire file into allocated memory, with good error
       
   853  * checking. 
       
   854  *
       
   855  * If the call was successful, it returns %TRUE and sets @contents to the file 
       
   856  * contents and @length to the length of the file contents in bytes. The string 
       
   857  * stored in @contents will be nul-terminated, so for text files you can pass 
       
   858  * %NULL for the @length argument. If the call was not successful, it returns 
       
   859  * %FALSE and sets @error. The error domain is #G_FILE_ERROR. Possible error  
       
   860  * codes are those in the #GFileError enumeration. In the error case, 
       
   861  * @contents is set to %NULL and @length is set to zero.
       
   862  *
       
   863  * Return value: %TRUE on success, %FALSE if an error occurred
       
   864  **/
       
   865 EXPORT_C gboolean
       
   866 g_file_get_contents (const gchar *filename,
       
   867                      gchar      **contents,
       
   868                      gsize       *length,
       
   869                      GError     **error)
       
   870 {  
       
   871   g_return_val_if_fail (filename != NULL, FALSE);
       
   872   g_return_val_if_fail (contents != NULL, FALSE);
       
   873 
       
   874   *contents = NULL;
       
   875   if (length)
       
   876     *length = 0;
       
   877 
       
   878 #ifdef G_OS_WIN32
       
   879   return get_contents_win32 (filename, contents, length, error);
       
   880 #else
       
   881   return get_contents_posix (filename, contents, length, error);
       
   882 #endif
       
   883 }
       
   884 
       
   885 #ifdef G_OS_WIN32
       
   886 
       
   887 #undef g_file_get_contents
       
   888 
       
   889 /* Binary compatibility version. Not for newly compiled code. */
       
   890 
       
   891 gboolean
       
   892 g_file_get_contents (const gchar *filename,
       
   893                      gchar      **contents,
       
   894                      gsize       *length,
       
   895                      GError     **error)
       
   896 {
       
   897   gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
       
   898   gboolean retval;
       
   899 
       
   900   if (utf8_filename == NULL)
       
   901     return FALSE;
       
   902 
       
   903   retval = g_file_get_contents_utf8 (utf8_filename, contents, length, error);
       
   904 
       
   905   g_free (utf8_filename);
       
   906 
       
   907   return retval;
       
   908 }
       
   909 
       
   910 #endif
       
   911 
       
   912 static gboolean
       
   913 rename_file (const char *old_name,
       
   914 	     const char *new_name,
       
   915 	     GError **err)
       
   916 {
       
   917   errno = 0;
       
   918   if (g_rename (old_name, new_name) == -1)
       
   919     {
       
   920       int save_errno = errno;
       
   921       gchar *display_old_name = g_filename_display_name (old_name);
       
   922       gchar *display_new_name = g_filename_display_name (new_name);
       
   923 
       
   924       g_set_error (err,
       
   925 		   G_FILE_ERROR,
       
   926 		   g_file_error_from_errno (save_errno),
       
   927 		   _("Failed to rename file '%s' to '%s': g_rename() failed: %s"),
       
   928 		   display_old_name,
       
   929 		   display_new_name,
       
   930 		   g_strerror (save_errno));
       
   931 
       
   932       g_free (display_old_name);
       
   933       g_free (display_new_name);
       
   934       
       
   935       return FALSE;
       
   936     }
       
   937   
       
   938   return TRUE;
       
   939 }
       
   940 
       
   941 static gchar *
       
   942 write_to_temp_file (const gchar *contents,
       
   943 		    gssize length,
       
   944 		    const gchar *template,
       
   945 		    GError **err)
       
   946 {
       
   947   gchar *tmp_name;
       
   948   gchar *display_name;
       
   949   gchar *retval;
       
   950   FILE *file;
       
   951   gint fd;
       
   952   int save_errno;
       
   953 
       
   954   retval = NULL;
       
   955   
       
   956   tmp_name = g_strdup_printf ("%s.XXXXXX", template);
       
   957 
       
   958   errno = 0;
       
   959   fd = create_temp_file (tmp_name, 0666);
       
   960   display_name = g_filename_display_name (tmp_name);
       
   961       
       
   962   if (fd == -1)
       
   963     {
       
   964       save_errno = errno;
       
   965       g_set_error (err,
       
   966 		   G_FILE_ERROR,
       
   967 		   g_file_error_from_errno (save_errno),
       
   968 		   _("Failed to create file '%s': %s"),
       
   969 		   display_name, g_strerror (save_errno));
       
   970       
       
   971       goto out;
       
   972     }
       
   973 
       
   974   errno = 0;
       
   975   file = fdopen (fd, "wb");
       
   976   if (!file)
       
   977     {
       
   978       save_errno = errno;
       
   979       g_set_error (err,
       
   980 		   G_FILE_ERROR,
       
   981 		   g_file_error_from_errno (save_errno),
       
   982 		   _("Failed to open file '%s' for writing: fdopen() failed: %s"),
       
   983 		   display_name,
       
   984 		   g_strerror (save_errno));
       
   985 
       
   986       close (fd);
       
   987       g_unlink (tmp_name);
       
   988       
       
   989       goto out;
       
   990     }
       
   991 
       
   992   if (length > 0)
       
   993     {
       
   994       size_t n_written;
       
   995       
       
   996       errno = 0;
       
   997 
       
   998       n_written = fwrite (contents, 1, length, file);
       
   999 
       
  1000       if (n_written < length)
       
  1001 	{
       
  1002 	  save_errno = errno;
       
  1003       
       
  1004  	  g_set_error (err,
       
  1005 		       G_FILE_ERROR,
       
  1006 		       g_file_error_from_errno (save_errno),
       
  1007 		       _("Failed to write file '%s': fwrite() failed: %s"),
       
  1008 		       display_name,
       
  1009 		       g_strerror (save_errno));
       
  1010 
       
  1011 	  fclose (file);
       
  1012 	  g_unlink (tmp_name);
       
  1013 	  
       
  1014 	  goto out;
       
  1015 	}
       
  1016     }
       
  1017    
       
  1018   errno = 0;
       
  1019   if (fclose (file) == EOF)
       
  1020     { 
       
  1021       save_errno = 0;
       
  1022       
       
  1023       g_set_error (err,
       
  1024 		   G_FILE_ERROR,
       
  1025 		   g_file_error_from_errno (save_errno),
       
  1026 		   _("Failed to close file '%s': fclose() failed: %s"),
       
  1027 		   display_name, 
       
  1028 		   g_strerror (save_errno));
       
  1029 
       
  1030       g_unlink (tmp_name);
       
  1031       
       
  1032       goto out;
       
  1033     }
       
  1034 
       
  1035   retval = g_strdup (tmp_name);
       
  1036   
       
  1037  out:
       
  1038   g_free (tmp_name);
       
  1039   g_free (display_name);
       
  1040   
       
  1041   return retval;
       
  1042 }
       
  1043 
       
  1044 /**
       
  1045  * g_file_set_contents:
       
  1046  * @filename: name of a file to write @contents to, in the GLib file name
       
  1047  *   encoding
       
  1048  * @contents: string to write to the file
       
  1049  * @length: length of @contents, or -1 if @contents is a nul-terminated string
       
  1050  * @error: return location for a #GError, or %NULL
       
  1051  *
       
  1052  * Writes all of @contents to a file named @filename, with good error checking.
       
  1053  * If a file called @filename already exists it will be overwritten.
       
  1054  *
       
  1055  * This write is atomic in the sense that it is first written to a temporary
       
  1056  * file which is then renamed to the final name. Notes:
       
  1057  * <itemizedlist>
       
  1058  * <listitem>
       
  1059  *    On Unix, if @filename already exists hard links to @filename will break.
       
  1060  *    Also since the file is recreated, existing permissions, access control
       
  1061  *    lists, metadata etc. may be lost. If @filename is a symbolic link,
       
  1062  *    the link itself will be replaced, not the linked file.
       
  1063  * </listitem>
       
  1064  * <listitem>
       
  1065  *   On Windows renaming a file will not remove an existing file with the
       
  1066  *   new name, so on Windows there is a race condition between the existing
       
  1067  *   file being removed and the temporary file being renamed.
       
  1068  * </listitem>
       
  1069  * <listitem>
       
  1070  *   On Windows there is no way to remove a file that is open to some
       
  1071  *   process, or mapped into memory. Thus, this function will fail if
       
  1072  *   @filename already exists and is open.
       
  1073  * </listitem>
       
  1074  * </itemizedlist>
       
  1075  *
       
  1076  * If the call was sucessful, it returns %TRUE. If the call was not successful,
       
  1077  * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
       
  1078  * Possible error codes are those in the #GFileError enumeration.
       
  1079  *
       
  1080  * Return value: %TRUE on success, %FALSE if an error occurred
       
  1081  *
       
  1082  * Since: 2.8
       
  1083  **/
       
  1084 EXPORT_C gboolean
       
  1085 g_file_set_contents (const gchar *filename,
       
  1086 		     const gchar *contents,
       
  1087 		     gssize	     length,
       
  1088 		     GError	   **error)
       
  1089 {
       
  1090   gchar *tmp_filename;
       
  1091   gboolean retval;
       
  1092   GError *rename_error = NULL;
       
  1093   
       
  1094   g_return_val_if_fail (filename != NULL, FALSE);
       
  1095   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
       
  1096   g_return_val_if_fail (contents != NULL || length == 0, FALSE);
       
  1097   g_return_val_if_fail (length >= -1, FALSE);
       
  1098   
       
  1099   if (length == -1)
       
  1100     length = strlen (contents);
       
  1101 
       
  1102   tmp_filename = write_to_temp_file (contents, length, filename, error);
       
  1103   
       
  1104   if (!tmp_filename)
       
  1105     {
       
  1106       retval = FALSE;
       
  1107       goto out;
       
  1108     }
       
  1109 
       
  1110   if (!rename_file (tmp_filename, filename, &rename_error))
       
  1111     {
       
  1112 #ifndef G_OS_WIN32
       
  1113 
       
  1114       g_unlink (tmp_filename);
       
  1115       g_propagate_error (error, rename_error);
       
  1116       retval = FALSE;
       
  1117       goto out;
       
  1118 
       
  1119 #else /* G_OS_WIN32 */
       
  1120       
       
  1121       /* Renaming failed, but on Windows this may just mean
       
  1122        * the file already exists. So if the target file
       
  1123        * exists, try deleting it and do the rename again.
       
  1124        */
       
  1125       if (!g_file_test (filename, G_FILE_TEST_EXISTS))
       
  1126 	{
       
  1127 	  g_unlink (tmp_filename);
       
  1128 	  g_propagate_error (error, rename_error);
       
  1129 	  retval = FALSE;
       
  1130 	  goto out;
       
  1131 	}
       
  1132 
       
  1133       g_error_free (rename_error);
       
  1134       
       
  1135       if (g_unlink (filename) == -1)
       
  1136 	{
       
  1137           gchar *display_filename = g_filename_display_name (filename);
       
  1138 
       
  1139 	  int save_errno = errno;
       
  1140 	  
       
  1141 	  g_set_error (error,
       
  1142 		       G_FILE_ERROR,
       
  1143 		       g_file_error_from_errno (save_errno),
       
  1144 		       _("Existing file '%s' could not be removed: g_unlink() failed: %s"),
       
  1145 		       display_filename,
       
  1146 		       g_strerror (save_errno));
       
  1147 
       
  1148 	  g_free (display_filename);
       
  1149 	  g_unlink (tmp_filename);
       
  1150 	  retval = FALSE;
       
  1151 	  goto out;
       
  1152 	}
       
  1153       
       
  1154       if (!rename_file (tmp_filename, filename, error))
       
  1155 	{
       
  1156 	  g_unlink (tmp_filename);
       
  1157 	  retval = FALSE;
       
  1158 	  goto out;
       
  1159 	}
       
  1160 
       
  1161 #endif
       
  1162     }
       
  1163 
       
  1164   retval = TRUE;
       
  1165   
       
  1166  out:
       
  1167   g_free (tmp_filename);
       
  1168   return retval;
       
  1169 }
       
  1170 
       
  1171 /*
       
  1172  * create_temp_file based on the mkstemp implementation from the GNU C library.
       
  1173  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
       
  1174  */
       
  1175  
       
  1176 #if EMULATOR
       
  1177 
       
  1178 PLS(counter ,create_temp_file,int)
       
  1179 #define counter (*FUNCTION_NAME(counter ,create_temp_file)())
       
  1180 
       
  1181 #endif /* EMULATOR */
       
  1182 
       
  1183 static gint
       
  1184 create_temp_file (gchar *tmpl, 
       
  1185 		  int    permissions)
       
  1186 {
       
  1187   int len;
       
  1188   char *XXXXXX;
       
  1189   int count, fd;
       
  1190   static const char letters[] =
       
  1191     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
       
  1192   static const int NLETTERS = sizeof (letters) - 1;
       
  1193   glong value;
       
  1194   GTimeVal tv;
       
  1195   
       
  1196   #if !(EMULATOR)
       
  1197   static int counter = 0;
       
  1198   #endif /*EMULATOR */
       
  1199 
       
  1200   len = strlen (tmpl);
       
  1201   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
       
  1202     {
       
  1203       errno = EINVAL;
       
  1204       return -1;
       
  1205     }
       
  1206 
       
  1207   /* This is where the Xs start.  */
       
  1208   XXXXXX = &tmpl[len - 6];
       
  1209 
       
  1210   /* Get some more or less random data.  */
       
  1211   g_get_current_time (&tv);
       
  1212   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
       
  1213 
       
  1214   for (count = 0; count < 100; value += 7777, ++count)
       
  1215     {
       
  1216       glong v = value;
       
  1217 
       
  1218       /* Fill in the random bits.  */
       
  1219       XXXXXX[0] = letters[v % NLETTERS];
       
  1220       v /= NLETTERS;
       
  1221       XXXXXX[1] = letters[v % NLETTERS];
       
  1222       v /= NLETTERS;
       
  1223       XXXXXX[2] = letters[v % NLETTERS];
       
  1224       v /= NLETTERS;
       
  1225       XXXXXX[3] = letters[v % NLETTERS];
       
  1226       v /= NLETTERS;
       
  1227       XXXXXX[4] = letters[v % NLETTERS];
       
  1228       v /= NLETTERS;
       
  1229       XXXXXX[5] = letters[v % NLETTERS];
       
  1230 
       
  1231       /* tmpl is in UTF-8 on Windows, thus use g_open() */
       
  1232       fd = g_open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, permissions);
       
  1233 
       
  1234       if (fd >= 0)
       
  1235 	return fd;
       
  1236       else if (errno != EEXIST)
       
  1237 	/* Any other error will apply also to other names we might
       
  1238 	 *  try, and there are 2^32 or so of them, so give up now.
       
  1239 	 */
       
  1240 	return -1;
       
  1241     }
       
  1242 
       
  1243   /* We got out of the loop because we ran out of combinations to try.  */
       
  1244   errno = EEXIST;
       
  1245   return -1;
       
  1246 }
       
  1247 
       
  1248 
       
  1249 #if EMULATOR
       
  1250 #undef counter
       
  1251 #endif /*EMULATOR */
       
  1252 
       
  1253 
       
  1254 
       
  1255 /**
       
  1256  * g_mkstemp:
       
  1257  * @tmpl: template filename
       
  1258  *
       
  1259  * Opens a temporary file. See the mkstemp() documentation
       
  1260  * on most UNIX-like systems. This is a portability wrapper, which simply calls 
       
  1261  * mkstemp() on systems that have it, and implements 
       
  1262  * it in GLib otherwise.
       
  1263  *
       
  1264  * The parameter is a string that should match the rules for
       
  1265  * mkstemp(), i.e. end in "XXXXXX". The X string will 
       
  1266  * be modified to form the name of a file that didn't exist.
       
  1267  * The string should be in the GLib file name encoding. Most importantly, 
       
  1268  * on Windows it should be in UTF-8.
       
  1269  *
       
  1270  * Return value: A file handle (as from open()) to the file
       
  1271  * opened for reading and writing. The file is opened in binary mode
       
  1272  * on platforms where there is a difference. The file handle should be
       
  1273  * closed with close(). In case of errors, -1 is returned.
       
  1274  */
       
  1275 EXPORT_C gint
       
  1276 g_mkstemp (gchar *tmpl)
       
  1277 {
       
  1278 #ifdef HAVE_MKSTEMP
       
  1279   return mkstemp (tmpl);
       
  1280 #else
       
  1281   return create_temp_file (tmpl, 0600);
       
  1282 #endif
       
  1283 }
       
  1284 
       
  1285 #ifdef G_OS_WIN32
       
  1286 
       
  1287 #undef g_mkstemp
       
  1288 
       
  1289 /* Binary compatibility version. Not for newly compiled code. */
       
  1290 
       
  1291 gint
       
  1292 g_mkstemp (gchar *tmpl)
       
  1293 {
       
  1294   int len;
       
  1295   char *XXXXXX;
       
  1296   int count, fd;
       
  1297   static const char letters[] =
       
  1298     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
       
  1299   static const int NLETTERS = sizeof (letters) - 1;
       
  1300   glong value;
       
  1301   GTimeVal tv;
       
  1302   static int counter = 0;
       
  1303 
       
  1304   len = strlen (tmpl);
       
  1305   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
       
  1306     {
       
  1307       errno = EINVAL;
       
  1308       return -1;
       
  1309     }
       
  1310 
       
  1311   /* This is where the Xs start.  */
       
  1312   XXXXXX = &tmpl[len - 6];
       
  1313 
       
  1314   /* Get some more or less random data.  */
       
  1315   g_get_current_time (&tv);
       
  1316   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
       
  1317 
       
  1318   for (count = 0; count < 100; value += 7777, ++count)
       
  1319     {
       
  1320       glong v = value;
       
  1321 
       
  1322       /* Fill in the random bits.  */
       
  1323       XXXXXX[0] = letters[v % NLETTERS];
       
  1324       v /= NLETTERS;
       
  1325       XXXXXX[1] = letters[v % NLETTERS];
       
  1326       v /= NLETTERS;
       
  1327       XXXXXX[2] = letters[v % NLETTERS];
       
  1328       v /= NLETTERS;
       
  1329       XXXXXX[3] = letters[v % NLETTERS];
       
  1330       v /= NLETTERS;
       
  1331       XXXXXX[4] = letters[v % NLETTERS];
       
  1332       v /= NLETTERS;
       
  1333       XXXXXX[5] = letters[v % NLETTERS];
       
  1334 
       
  1335       /* This is the backward compatibility system codepage version,
       
  1336        * thus use normal open().
       
  1337        */
       
  1338       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
       
  1339 
       
  1340       if (fd >= 0)
       
  1341 	return fd;
       
  1342       else if (errno != EEXIST)
       
  1343 	/* Any other error will apply also to other names we might
       
  1344 	 *  try, and there are 2^32 or so of them, so give up now.
       
  1345 	 */
       
  1346 	return -1;
       
  1347     }
       
  1348 
       
  1349   /* We got out of the loop because we ran out of combinations to try.  */
       
  1350   errno = EEXIST;
       
  1351   return -1;
       
  1352 }
       
  1353 
       
  1354 #endif
       
  1355 
       
  1356 /**
       
  1357  * g_file_open_tmp:
       
  1358  * @tmpl: Template for file name, as in g_mkstemp(), basename only
       
  1359  * @name_used: location to store actual name used
       
  1360  * @error: return location for a #GError
       
  1361  *
       
  1362  * Opens a file for writing in the preferred directory for temporary
       
  1363  * files (as returned by g_get_tmp_dir()). 
       
  1364  *
       
  1365  * @tmpl should be a string in the GLib file name encoding ending with
       
  1366  * six 'X' characters, as the parameter to g_mkstemp() (or mkstemp()).
       
  1367  * However, unlike these functions, the template should only be a
       
  1368  * basename, no directory components are allowed. If template is
       
  1369  * %NULL, a default template is used.
       
  1370  *
       
  1371  * Note that in contrast to g_mkstemp() (and mkstemp()) 
       
  1372  * @tmpl is not modified, and might thus be a read-only literal string.
       
  1373  *
       
  1374  * The actual name used is returned in @name_used if non-%NULL. This
       
  1375  * string should be freed with g_free() when not needed any longer.
       
  1376  * The returned name is in the GLib file name encoding.
       
  1377  *
       
  1378  * Return value: A file handle (as from open()) to 
       
  1379  * the file opened for reading and writing. The file is opened in binary 
       
  1380  * mode on platforms where there is a difference. The file handle should be
       
  1381  * closed with close(). In case of errors, -1 is returned 
       
  1382  * and @error will be set.
       
  1383  **/
       
  1384 EXPORT_C gint
       
  1385 g_file_open_tmp (const gchar *tmpl,
       
  1386 		 gchar      **name_used,
       
  1387 		 GError     **error)
       
  1388 {
       
  1389   int retval;
       
  1390   const char *tmpdir;
       
  1391   char *sep;
       
  1392   char *fulltemplate;
       
  1393   const char *slash;
       
  1394 
       
  1395   if (tmpl == NULL)
       
  1396     tmpl = ".XXXXXX";
       
  1397 
       
  1398   if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
       
  1399 #ifdef G_OS_WIN32
       
  1400       || (strchr (tmpl, '/') != NULL && (slash = "/"))
       
  1401 #endif
       
  1402       )
       
  1403     {
       
  1404       gchar *display_tmpl = g_filename_display_name (tmpl);
       
  1405       char c[2];
       
  1406       c[0] = *slash;
       
  1407       c[1] = '\0';
       
  1408 
       
  1409       g_set_error (error,
       
  1410 		   G_FILE_ERROR,
       
  1411 		   G_FILE_ERROR_FAILED,
       
  1412 		   _("Template '%s' invalid, should not contain a '%s'"),
       
  1413 		   display_tmpl, c);
       
  1414       g_free (display_tmpl);
       
  1415 
       
  1416       return -1;
       
  1417     }
       
  1418   
       
  1419   if (strlen (tmpl) < 6 ||
       
  1420       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
       
  1421     {
       
  1422       gchar *display_tmpl = g_filename_display_name (tmpl);
       
  1423       g_set_error (error,
       
  1424 		   G_FILE_ERROR,
       
  1425 		   G_FILE_ERROR_FAILED,
       
  1426 		   _("Template '%s' doesn't end with XXXXXX"),
       
  1427 		   display_tmpl);
       
  1428       g_free (display_tmpl);
       
  1429       return -1;
       
  1430     }
       
  1431 
       
  1432   tmpdir = g_get_tmp_dir ();
       
  1433 
       
  1434   mkdir("C:\\Private\\e000002c\\tmp", 0666);
       
  1435   if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
       
  1436     sep = "";
       
  1437   else
       
  1438     sep = G_DIR_SEPARATOR_S;
       
  1439 
       
  1440   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
       
  1441 
       
  1442   retval = g_mkstemp (fulltemplate);
       
  1443 
       
  1444   if (retval == -1)
       
  1445     {
       
  1446       int save_errno = errno;
       
  1447       gchar *display_fulltemplate = g_filename_display_name (fulltemplate);
       
  1448 
       
  1449       g_set_error (error,
       
  1450 		   G_FILE_ERROR,
       
  1451 		   g_file_error_from_errno (save_errno),
       
  1452 		   _("Failed to create file '%s': %s"),
       
  1453 		   display_fulltemplate, g_strerror (save_errno));
       
  1454       g_free (display_fulltemplate);
       
  1455       g_free (fulltemplate);
       
  1456       return -1;
       
  1457     }
       
  1458 
       
  1459   if (name_used)
       
  1460     *name_used = fulltemplate;
       
  1461   else
       
  1462     g_free (fulltemplate);
       
  1463 
       
  1464   return retval;
       
  1465 }
       
  1466 
       
  1467 #ifdef G_OS_WIN32
       
  1468 
       
  1469 #undef g_file_open_tmp
       
  1470 
       
  1471 /* Binary compatibility version. Not for newly compiled code. */
       
  1472 
       
  1473 gint
       
  1474 g_file_open_tmp (const gchar *tmpl,
       
  1475 		 gchar      **name_used,
       
  1476 		 GError     **error)
       
  1477 {
       
  1478   gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error);
       
  1479   gchar *utf8_name_used;
       
  1480   gint retval;
       
  1481 
       
  1482   if (utf8_tmpl == NULL)
       
  1483     return -1;
       
  1484 
       
  1485   retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error);
       
  1486   
       
  1487   if (retval == -1)
       
  1488     return -1;
       
  1489 
       
  1490   if (name_used)
       
  1491     *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL);
       
  1492 
       
  1493   g_free (utf8_name_used);
       
  1494 
       
  1495   return retval;
       
  1496 }
       
  1497 
       
  1498 #endif
       
  1499 
       
  1500 static gchar *
       
  1501 g_build_path_va (const gchar  *separator,
       
  1502 		 const gchar  *first_element,
       
  1503 		 va_list      *args,
       
  1504 		 gchar       **str_array)
       
  1505 {
       
  1506   GString *result;
       
  1507   gint separator_len = strlen (separator);
       
  1508   gboolean is_first = TRUE;
       
  1509   gboolean have_leading = FALSE;
       
  1510   const gchar *single_element = NULL;
       
  1511   const gchar *next_element;
       
  1512   const gchar *last_trailing = NULL;
       
  1513   gint i = 0;
       
  1514 
       
  1515   result = g_string_new (NULL);
       
  1516 
       
  1517   if (str_array)
       
  1518     next_element = str_array[i++];
       
  1519   else
       
  1520     next_element = first_element;
       
  1521 
       
  1522   while (TRUE)
       
  1523     {
       
  1524       const gchar *element;
       
  1525       const gchar *start;
       
  1526       const gchar *end;
       
  1527 
       
  1528       if (next_element)
       
  1529 	{
       
  1530 	  element = next_element;
       
  1531 	  if (str_array)
       
  1532 	    next_element = str_array[i++];
       
  1533 	  else
       
  1534 	    next_element = va_arg (*args, gchar *);
       
  1535 	}
       
  1536       else
       
  1537 	break;
       
  1538 
       
  1539       /* Ignore empty elements */
       
  1540       if (!*element)
       
  1541 	continue;
       
  1542       
       
  1543       start = element;
       
  1544 
       
  1545       if (separator_len)
       
  1546 	{
       
  1547 	  while (start &&
       
  1548 		 strncmp (start, separator, separator_len) == 0)
       
  1549 	    start += separator_len;
       
  1550       	}
       
  1551 
       
  1552       end = start + strlen (start);
       
  1553       
       
  1554       if (separator_len)
       
  1555 	{
       
  1556 	  while (end >= start + separator_len &&
       
  1557 		 strncmp (end - separator_len, separator, separator_len) == 0)
       
  1558 	    end -= separator_len;
       
  1559 	  
       
  1560 	  last_trailing = end;
       
  1561 	  while (last_trailing >= element + separator_len &&
       
  1562 		 strncmp (last_trailing - separator_len, separator, separator_len) == 0)
       
  1563 	    last_trailing -= separator_len;
       
  1564 
       
  1565 	  if (!have_leading)
       
  1566 	    {
       
  1567 	      /* If the leading and trailing separator strings are in the
       
  1568 	       * same element and overlap, the result is exactly that element
       
  1569 	       */
       
  1570 	      if (last_trailing <= start)
       
  1571 		single_element = element;
       
  1572 		  
       
  1573 	      g_string_append_len (result, element, start - element);
       
  1574 	      have_leading = TRUE;
       
  1575 	    }
       
  1576 	  else
       
  1577 	    single_element = NULL;
       
  1578 	}
       
  1579 
       
  1580       if (end == start)
       
  1581 	continue;
       
  1582 
       
  1583       if (!is_first)
       
  1584 	g_string_append (result, separator);
       
  1585       
       
  1586       g_string_append_len (result, start, end - start);
       
  1587       is_first = FALSE;
       
  1588     }
       
  1589 
       
  1590   if (single_element)
       
  1591     {
       
  1592       g_string_free (result, TRUE);
       
  1593       return g_strdup (single_element);
       
  1594     }
       
  1595   else
       
  1596     {
       
  1597       if (last_trailing)
       
  1598 	g_string_append (result, last_trailing);
       
  1599   
       
  1600       return g_string_free (result, FALSE);
       
  1601     }
       
  1602 }
       
  1603 
       
  1604 /**
       
  1605  * g_build_pathv:
       
  1606  * @separator: a string used to separator the elements of the path.
       
  1607  * @args: %NULL-terminated array of strings containing the path elements.
       
  1608  * 
       
  1609  * Behaves exactly like g_build_path(), but takes the path elements 
       
  1610  * as a string array, instead of varargs. This function is mainly
       
  1611  * meant for language bindings.
       
  1612  *
       
  1613  * Return value: a newly-allocated string that must be freed with g_free().
       
  1614  *
       
  1615  * Since: 2.8
       
  1616  */
       
  1617 EXPORT_C gchar *
       
  1618 g_build_pathv (const gchar  *separator,
       
  1619 	       gchar       **args)
       
  1620 {
       
  1621   if (!args)
       
  1622     return NULL;
       
  1623 
       
  1624   return g_build_path_va (separator, NULL, NULL, args);
       
  1625 }
       
  1626 
       
  1627 
       
  1628 /**
       
  1629  * g_build_path:
       
  1630  * @separator: a string used to separator the elements of the path.
       
  1631  * @first_element: the first element in the path
       
  1632  * @Varargs: remaining elements in path, terminated by %NULL
       
  1633  * 
       
  1634  * Creates a path from a series of elements using @separator as the
       
  1635  * separator between elements. At the boundary between two elements,
       
  1636  * any trailing occurrences of separator in the first element, or
       
  1637  * leading occurrences of separator in the second element are removed
       
  1638  * and exactly one copy of the separator is inserted.
       
  1639  *
       
  1640  * Empty elements are ignored.
       
  1641  *
       
  1642  * The number of leading copies of the separator on the result is
       
  1643  * the same as the number of leading copies of the separator on
       
  1644  * the first non-empty element.
       
  1645  *
       
  1646  * The number of trailing copies of the separator on the result is
       
  1647  * the same as the number of trailing copies of the separator on
       
  1648  * the last non-empty element. (Determination of the number of
       
  1649  * trailing copies is done without stripping leading copies, so
       
  1650  * if the separator is <literal>ABA</literal>, <literal>ABABA</literal>
       
  1651  * has 1 trailing copy.)
       
  1652  *
       
  1653  * However, if there is only a single non-empty element, and there
       
  1654  * are no characters in that element not part of the leading or
       
  1655  * trailing separators, then the result is exactly the original value
       
  1656  * of that element.
       
  1657  *
       
  1658  * Other than for determination of the number of leading and trailing
       
  1659  * copies of the separator, elements consisting only of copies
       
  1660  * of the separator are ignored.
       
  1661  * 
       
  1662  * Return value: a newly-allocated string that must be freed with g_free().
       
  1663  **/
       
  1664 EXPORT_C gchar *
       
  1665 g_build_path (const gchar *separator,
       
  1666 	      const gchar *first_element,
       
  1667 	      ...)
       
  1668 {
       
  1669   gchar *str;
       
  1670   va_list args;
       
  1671 
       
  1672   g_return_val_if_fail (separator != NULL, NULL);
       
  1673 
       
  1674   va_start (args, first_element);
       
  1675   str = g_build_path_va (separator, first_element, &args, NULL);
       
  1676   va_end (args);
       
  1677 
       
  1678   return str;
       
  1679 }
       
  1680 
       
  1681 #ifdef G_OS_WIN32
       
  1682 
       
  1683 static gchar *
       
  1684 g_build_pathname_va (const gchar  *first_element,
       
  1685 		     va_list      *args,
       
  1686 		     gchar       **str_array)
       
  1687 {
       
  1688   /* Code copied from g_build_pathv(), and modified to use two
       
  1689    * alternative single-character separators.
       
  1690    */
       
  1691   GString *result;
       
  1692   gboolean is_first = TRUE;
       
  1693   gboolean have_leading = FALSE;
       
  1694   const gchar *single_element = NULL;
       
  1695   const gchar *next_element;
       
  1696   const gchar *last_trailing = NULL;
       
  1697   gchar current_separator = '\\';
       
  1698   gint i = 0;
       
  1699 
       
  1700   result = g_string_new (NULL);
       
  1701 
       
  1702   if (str_array)
       
  1703     next_element = str_array[i++];
       
  1704   else
       
  1705     next_element = first_element;
       
  1706   
       
  1707   while (TRUE)
       
  1708     {
       
  1709       const gchar *element;
       
  1710       const gchar *start;
       
  1711       const gchar *end;
       
  1712 
       
  1713       if (next_element)
       
  1714 	{
       
  1715 	  element = next_element;
       
  1716 	  if (str_array)
       
  1717 	    next_element = str_array[i++];
       
  1718 	  else
       
  1719 	    next_element = va_arg (*args, gchar *);
       
  1720 	}
       
  1721       else
       
  1722 	break;
       
  1723 
       
  1724       /* Ignore empty elements */
       
  1725       if (!*element)
       
  1726 	continue;
       
  1727       
       
  1728       start = element;
       
  1729 
       
  1730       if (TRUE)
       
  1731 	{
       
  1732 	  while (start &&
       
  1733 		 (*start == '\\' || *start == '/'))
       
  1734 	    {
       
  1735 	      current_separator = *start;
       
  1736 	      start++;
       
  1737 	    }
       
  1738 	}
       
  1739 
       
  1740       end = start + strlen (start);
       
  1741       
       
  1742       if (TRUE)
       
  1743 	{
       
  1744 	  while (end >= start + 1 &&
       
  1745 		 (end[-1] == '\\' || end[-1] == '/'))
       
  1746 	    {
       
  1747 	      current_separator = end[-1];
       
  1748 	      end--;
       
  1749 	    }
       
  1750 	  
       
  1751 	  last_trailing = end;
       
  1752 	  while (last_trailing >= element + 1 &&
       
  1753 		 (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
       
  1754 	    last_trailing--;
       
  1755 
       
  1756 	  if (!have_leading)
       
  1757 	    {
       
  1758 	      /* If the leading and trailing separator strings are in the
       
  1759 	       * same element and overlap, the result is exactly that element
       
  1760 	       */
       
  1761 	      if (last_trailing <= start)
       
  1762 		single_element = element;
       
  1763 		  
       
  1764 	      g_string_append_len (result, element, start - element);
       
  1765 	      have_leading = TRUE;
       
  1766 	    }
       
  1767 	  else
       
  1768 	    single_element = NULL;
       
  1769 	}
       
  1770 
       
  1771       if (end == start)
       
  1772 	continue;
       
  1773 
       
  1774       if (!is_first)
       
  1775 	g_string_append_len (result, &current_separator, 1);
       
  1776       
       
  1777       g_string_append_len (result, start, end - start);
       
  1778       is_first = FALSE;
       
  1779     }
       
  1780 
       
  1781   if (single_element)
       
  1782     {
       
  1783       g_string_free (result, TRUE);
       
  1784       return g_strdup (single_element);
       
  1785     }
       
  1786   else
       
  1787     {
       
  1788       if (last_trailing)
       
  1789 	g_string_append (result, last_trailing);
       
  1790   
       
  1791       return g_string_free (result, FALSE);
       
  1792     }
       
  1793 }
       
  1794 
       
  1795 #endif
       
  1796 
       
  1797 /**
       
  1798  * g_build_filenamev:
       
  1799  * @args: %NULL-terminated array of strings containing the path elements.
       
  1800  * 
       
  1801  * Behaves exactly like g_build_filename(), but takes the path elements 
       
  1802  * as a string array, instead of varargs. This function is mainly
       
  1803  * meant for language bindings.
       
  1804  *
       
  1805  * Return value: a newly-allocated string that must be freed with g_free().
       
  1806  * 
       
  1807  * Since: 2.8
       
  1808  */
       
  1809 EXPORT_C gchar *
       
  1810 g_build_filenamev (gchar **args)
       
  1811 {
       
  1812   gchar *str;
       
  1813 
       
  1814 #ifndef G_OS_WIN32
       
  1815   str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, NULL, args);
       
  1816 #else
       
  1817   str = g_build_pathname_va (NULL, NULL, args);
       
  1818 #endif
       
  1819 
       
  1820   return str;
       
  1821 }
       
  1822 
       
  1823 /**
       
  1824  * g_build_filename:
       
  1825  * @first_element: the first element in the path
       
  1826  * @Varargs: remaining elements in path, terminated by %NULL
       
  1827  * 
       
  1828  * Creates a filename from a series of elements using the correct
       
  1829  * separator for filenames.
       
  1830  *
       
  1831  * On Unix, this function behaves identically to <literal>g_build_path
       
  1832  * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
       
  1833  *
       
  1834  * On Windows, it takes into account that either the backslash
       
  1835  * (<literal>\</literal> or slash (<literal>/</literal>) can be used
       
  1836  * as separator in filenames, but otherwise behaves as on Unix. When
       
  1837  * file pathname separators need to be inserted, the one that last
       
  1838  * previously occurred in the parameters (reading from left to right)
       
  1839  * is used.
       
  1840  *
       
  1841  * No attempt is made to force the resulting filename to be an absolute
       
  1842  * path. If the first element is a relative path, the result will
       
  1843  * be a relative path. 
       
  1844  * 
       
  1845  * Return value: a newly-allocated string that must be freed with g_free().
       
  1846  **/
       
  1847 EXPORT_C gchar *
       
  1848 g_build_filename (const gchar *first_element, 
       
  1849 		  ...)
       
  1850 {
       
  1851   gchar *str;
       
  1852   va_list args;
       
  1853 
       
  1854   va_start (args, first_element);
       
  1855 #ifndef G_OS_WIN32
       
  1856   str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, &args, NULL);
       
  1857 #else
       
  1858   str = g_build_pathname_va (first_element, &args, NULL);
       
  1859 #endif
       
  1860   va_end (args);
       
  1861 
       
  1862   return str;
       
  1863 }
       
  1864 
       
  1865 /**
       
  1866  * g_file_read_link:
       
  1867  * @filename: the symbolic link
       
  1868  * @error: return location for a #GError
       
  1869  *
       
  1870  * Reads the contents of the symbolic link @filename like the POSIX
       
  1871  * readlink() function.  The returned string is in the encoding used
       
  1872  * for filenames. Use g_filename_to_utf8() to convert it to UTF-8.
       
  1873  *
       
  1874  * Returns: A newly allocated string with the contents of the symbolic link, 
       
  1875  *          or %NULL if an error occurred.
       
  1876  *
       
  1877  * Since: 2.4
       
  1878  */
       
  1879 EXPORT_C gchar *
       
  1880 g_file_read_link (const gchar *filename,
       
  1881 	          GError     **error)
       
  1882 {
       
  1883 #ifdef HAVE_READLINK
       
  1884   gchar *buffer;
       
  1885   guint size;
       
  1886   gint read_size;    
       
  1887   
       
  1888   size = 256; 
       
  1889 
       
  1890   buffer = g_malloc (size);
       
  1891   
       
  1892   while (TRUE) 
       
  1893     {
       
  1894       read_size = readlink (filename, buffer, size);
       
  1895       if (read_size < 0) {
       
  1896 	int save_errno = errno;
       
  1897 	gchar *display_filename = g_filename_display_name (filename);
       
  1898 
       
  1899 	g_free (buffer);
       
  1900 	g_set_error (error,
       
  1901 		     G_FILE_ERROR,
       
  1902 		     g_file_error_from_errno (save_errno),
       
  1903 		     _("Failed to read the symbolic link '%s': %s"),
       
  1904 		     display_filename, 
       
  1905 		     g_strerror (save_errno));
       
  1906 	g_free (display_filename);
       
  1907 	
       
  1908 	return NULL;
       
  1909       }
       
  1910     
       
  1911       if (read_size < size) 
       
  1912 	{
       
  1913 	  buffer[read_size] = 0;
       
  1914 	  return buffer;
       
  1915 	}
       
  1916       
       
  1917       size *= 2;
       
  1918       buffer = g_realloc (buffer, size);
       
  1919     }
       
  1920 #else
       
  1921   g_set_error (error,
       
  1922 	       G_FILE_ERROR,
       
  1923 	       G_FILE_ERROR_INVAL,
       
  1924 	       _("Symbolic links not supported"));
       
  1925 	
       
  1926   return NULL;
       
  1927 #endif
       
  1928 }
       
  1929 
       
  1930 #define __G_FILEUTILS_C__
       
  1931 #include "galiasdef.c"