source: trunk/third/glib2/glib/gfileutils.c @ 21369

Revision 21369, 28.9 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21368, which included commits to RCS files with non-trunk default branches.
Line 
1/* gfileutils.c - File utility functions
2 *
3 *  Copyright 2000 Red Hat, Inc.
4 *
5 * GLib is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * GLib is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with GLib; see the file COPYING.LIB.  If not,
17 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 *   Boston, MA 02111-1307, USA.
19 */
20
21#include "config.h"
22
23#include "glib.h"
24
25#include <sys/stat.h>
26#ifdef HAVE_UNISTD_H
27#include <unistd.h>
28#endif
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <string.h>
33#include <errno.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <stdlib.h>
38
39#ifdef G_OS_WIN32
40#include <io.h>
41#ifndef F_OK
42#define F_OK 0
43#define W_OK 2
44#define R_OK 4
45#endif /* !F_OK */
46
47#ifndef S_ISREG
48#define S_ISREG(mode) ((mode)&_S_IFREG)
49#endif
50
51#ifndef S_ISDIR
52#define S_ISDIR(mode) ((mode)&_S_IFDIR)
53#endif
54
55#endif /* G_OS_WIN32 */
56
57#ifndef S_ISLNK
58#define S_ISLNK(x) 0
59#endif
60
61#ifndef O_BINARY
62#define O_BINARY 0
63#endif
64
65#include "glibintl.h"
66
67#ifdef G_OS_WIN32
68#define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR || c == '/')
69#else
70#define G_IS_DIR_SEPARATOR(c) (c == G_DIR_SEPARATOR)
71#endif
72
73/**
74 * g_file_test:
75 * @filename: a filename to test
76 * @test: bitfield of #GFileTest flags
77 *
78 * Returns %TRUE if any of the tests in the bitfield @test are
79 * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS |
80 * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists;
81 * the check whether it's a directory doesn't matter since the existence
82 * test is %TRUE. With the current set of available tests, there's no point
83 * passing in more than one test at a time.
84 *
85 * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
86 * so for a symbolic link to a regular file g_file_test() will return
87 * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
88 *
89 * Note, that for a dangling symbolic link g_file_test() will return
90 * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
91 *
92 * You should never use g_file_test() to test whether it is safe
93 * to perform an operaton, because there is always the possibility
94 * of the condition changing before you actually perform the operation.
95 * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
96 * to know whether it is is safe to write to a file without being
97 * tricked into writing into a different location. It doesn't work!
98 *
99 * <informalexample><programlisting>
100 * /&ast; DON'T DO THIS &ast;/
101 *  if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) {
102 *    fd = open (filename, O_WRONLY);
103 *    /&ast; write to fd &ast;/
104 *  }
105 * </programlisting></informalexample>
106 *
107 * Another thing to note is that %G_FILE_TEST_EXISTS and
108 * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
109 * system call. This usually doesn't matter, but if your program
110 * is setuid or setgid it means that these tests will give you
111 * the answer for the real user ID and group ID , rather than the
112 * effective user ID and group ID.
113 *
114 * Return value: whether a test was %TRUE
115 **/
116gboolean
117g_file_test (const gchar *filename,
118             GFileTest    test)
119{
120  if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
121    return TRUE;
122 
123#ifndef G_OS_WIN32
124  if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
125    {
126      if (getuid () != 0)
127        return TRUE;
128
129      /* For root, on some POSIX systems, access (filename, X_OK)
130       * will succeed even if no executable bits are set on the
131       * file. We fall through to a stat test to avoid that.
132       */
133    }
134  else
135    test &= ~G_FILE_TEST_IS_EXECUTABLE;
136#endif 
137
138  if (test & G_FILE_TEST_IS_SYMLINK)
139    {
140#ifdef G_OS_WIN32
141      /* no sym links on win32, no lstat in msvcrt */
142#else
143      struct stat s;
144
145      if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
146        return TRUE;
147#endif
148    }
149 
150  if (test & (G_FILE_TEST_IS_REGULAR |
151              G_FILE_TEST_IS_DIR |
152              G_FILE_TEST_IS_EXECUTABLE))
153    {
154      struct stat s;
155     
156      if (stat (filename, &s) == 0)
157        {
158          if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
159            return TRUE;
160         
161          if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
162            return TRUE;
163
164#ifndef G_OS_WIN32
165          /* The extra test for root when access (file, X_OK) succeeds.
166           * Probably only makes sense on Unix.
167           */
168          if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
169              ((s.st_mode & S_IXOTH) ||
170               (s.st_mode & S_IXUSR) ||
171               (s.st_mode & S_IXGRP)))
172            return TRUE;
173#else
174          if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
175              (s.st_mode & _S_IEXEC))
176            return TRUE;
177#endif
178        }
179    }
180
181  return FALSE;
182}
183
184GQuark
185g_file_error_quark (void)
186{
187  static GQuark q = 0;
188  if (q == 0)
189    q = g_quark_from_static_string ("g-file-error-quark");
190
191  return q;
192}
193
194/**
195 * g_file_error_from_errno:
196 * @err_no: an "errno" value
197 *
198 * Gets a #GFileError constant based on the passed-in @errno.
199 * For example, if you pass in %EEXIST this function returns
200 * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably
201 * assume that all #GFileError values will exist.
202 *
203 * Normally a #GFileError value goes into a #GError returned
204 * from a function that manipulates files. So you would use
205 * g_file_error_from_errno() when constructing a #GError.
206 *
207 * Return value: #GFileError corresponding to the given @errno
208 **/
209GFileError
210g_file_error_from_errno (gint err_no)
211{
212  switch (err_no)
213    {
214#ifdef EEXIST
215    case EEXIST:
216      return G_FILE_ERROR_EXIST;
217      break;
218#endif
219
220#ifdef EISDIR
221    case EISDIR:
222      return G_FILE_ERROR_ISDIR;
223      break;
224#endif
225
226#ifdef EACCES
227    case EACCES:
228      return G_FILE_ERROR_ACCES;
229      break;
230#endif
231
232#ifdef ENAMETOOLONG
233    case ENAMETOOLONG:
234      return G_FILE_ERROR_NAMETOOLONG;
235      break;
236#endif
237
238#ifdef ENOENT
239    case ENOENT:
240      return G_FILE_ERROR_NOENT;
241      break;
242#endif
243
244#ifdef ENOTDIR
245    case ENOTDIR:
246      return G_FILE_ERROR_NOTDIR;
247      break;
248#endif
249
250#ifdef ENXIO
251    case ENXIO:
252      return G_FILE_ERROR_NXIO;
253      break;
254#endif
255
256#ifdef ENODEV
257    case ENODEV:
258      return G_FILE_ERROR_NODEV;
259      break;
260#endif
261
262#ifdef EROFS
263    case EROFS:
264      return G_FILE_ERROR_ROFS;
265      break;
266#endif
267
268#ifdef ETXTBSY
269    case ETXTBSY:
270      return G_FILE_ERROR_TXTBSY;
271      break;
272#endif
273
274#ifdef EFAULT
275    case EFAULT:
276      return G_FILE_ERROR_FAULT;
277      break;
278#endif
279
280#ifdef ELOOP
281    case ELOOP:
282      return G_FILE_ERROR_LOOP;
283      break;
284#endif
285
286#ifdef ENOSPC
287    case ENOSPC:
288      return G_FILE_ERROR_NOSPC;
289      break;
290#endif
291
292#ifdef ENOMEM
293    case ENOMEM:
294      return G_FILE_ERROR_NOMEM;
295      break;
296#endif
297
298#ifdef EMFILE
299    case EMFILE:
300      return G_FILE_ERROR_MFILE;
301      break;
302#endif
303
304#ifdef ENFILE
305    case ENFILE:
306      return G_FILE_ERROR_NFILE;
307      break;
308#endif
309
310#ifdef EBADF
311    case EBADF:
312      return G_FILE_ERROR_BADF;
313      break;
314#endif
315
316#ifdef EINVAL
317    case EINVAL:
318      return G_FILE_ERROR_INVAL;
319      break;
320#endif
321
322#ifdef EPIPE
323    case EPIPE:
324      return G_FILE_ERROR_PIPE;
325      break;
326#endif
327
328#ifdef EAGAIN
329    case EAGAIN:
330      return G_FILE_ERROR_AGAIN;
331      break;
332#endif
333
334#ifdef EINTR
335    case EINTR:
336      return G_FILE_ERROR_INTR;
337      break;
338#endif
339
340#ifdef EIO
341    case EIO:
342      return G_FILE_ERROR_IO;
343      break;
344#endif
345
346#ifdef EPERM
347    case EPERM:
348      return G_FILE_ERROR_PERM;
349      break;
350#endif
351     
352    default:
353      return G_FILE_ERROR_FAILED;
354      break;
355    }
356}
357
358static gboolean
359get_contents_stdio (const gchar *filename,
360                    FILE        *f,
361                    gchar      **contents,
362                    gsize       *length,
363                    GError     **error)
364{
365  gchar buf[2048];
366  size_t bytes;
367  char *str;
368  size_t total_bytes;
369  size_t total_allocated;
370 
371  g_assert (f != NULL);
372
373#define STARTING_ALLOC 64
374 
375  total_bytes = 0;
376  total_allocated = STARTING_ALLOC;
377  str = g_malloc (STARTING_ALLOC);
378 
379  while (!feof (f))
380    {
381      bytes = fread (buf, 1, 2048, f);
382
383      while ((total_bytes + bytes + 1) > total_allocated)
384        {
385          total_allocated *= 2;
386          str = g_try_realloc (str, total_allocated);
387
388          if (str == NULL)
389            {
390              gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
391                                                         NULL, NULL, NULL);
392              g_set_error (error,
393                           G_FILE_ERROR,
394                           G_FILE_ERROR_NOMEM,
395                           _("Could not allocate %lu bytes to read file \"%s\""),
396                           (gulong) total_allocated,
397                           utf8_filename ? utf8_filename : "???");
398              g_free (utf8_filename);
399
400              goto error;
401            }
402        }
403     
404      if (ferror (f))
405        {
406          gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
407                                                     NULL, NULL, NULL);
408          g_set_error (error,
409                       G_FILE_ERROR,
410                       g_file_error_from_errno (errno),
411                       _("Error reading file '%s': %s"),
412                       utf8_filename ? utf8_filename : "???",
413                       g_strerror (errno));
414          g_free (utf8_filename);
415
416          goto error;
417        }
418
419      memcpy (str + total_bytes, buf, bytes);
420      total_bytes += bytes;
421    }
422
423  fclose (f);
424
425  str[total_bytes] = '\0';
426 
427  if (length)
428    *length = total_bytes;
429 
430  *contents = str;
431 
432  return TRUE;
433
434 error:
435
436  g_free (str);
437  fclose (f);
438 
439  return FALSE; 
440}
441
442#ifndef G_OS_WIN32
443
444static gboolean
445get_contents_regfile (const gchar *filename,
446                      struct stat *stat_buf,
447                      gint         fd,
448                      gchar      **contents,
449                      gsize       *length,
450                      GError     **error)
451{
452  gchar *buf;
453  size_t bytes_read;
454  size_t size;
455  size_t alloc_size;
456 
457  size = stat_buf->st_size;
458
459  alloc_size = size + 1;
460  buf = g_try_malloc (alloc_size);
461
462  if (buf == NULL)
463    {
464      gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
465                                                 NULL, NULL, NULL);
466      g_set_error (error,
467                   G_FILE_ERROR,
468                   G_FILE_ERROR_NOMEM,
469                   _("Could not allocate %lu bytes to read file \"%s\""),
470                   (gulong) alloc_size,
471                   utf8_filename ? utf8_filename : "???");
472      g_free (utf8_filename);
473
474      goto error;
475    }
476 
477  bytes_read = 0;
478  while (bytes_read < size)
479    {
480      gssize rc;
481         
482      rc = read (fd, buf + bytes_read, size - bytes_read);
483
484      if (rc < 0)
485        {
486          if (errno != EINTR)
487            {
488              gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
489                                                         NULL, NULL, NULL);
490              g_free (buf);
491              g_set_error (error,
492                           G_FILE_ERROR,
493                           g_file_error_from_errno (errno),
494                           _("Failed to read from file '%s': %s"),
495                           utf8_filename ? utf8_filename : "???",
496                           g_strerror (errno));
497              g_free (utf8_filename);
498
499              goto error;
500            }
501        }
502      else if (rc == 0)
503        break;
504      else
505        bytes_read += rc;
506    }
507     
508  buf[bytes_read] = '\0';
509
510  if (length)
511    *length = bytes_read;
512 
513  *contents = buf;
514
515  close (fd);
516
517  return TRUE;
518
519 error:
520
521  close (fd);
522 
523  return FALSE;
524}
525
526static gboolean
527get_contents_posix (const gchar *filename,
528                    gchar      **contents,
529                    gsize       *length,
530                    GError     **error)
531{
532  struct stat stat_buf;
533  gint fd;
534 
535  /* O_BINARY useful on Cygwin */
536  fd = open (filename, O_RDONLY|O_BINARY);
537
538  if (fd < 0)
539    {
540      gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
541                                                 NULL, NULL, NULL);
542      g_set_error (error,
543                   G_FILE_ERROR,
544                   g_file_error_from_errno (errno),
545                   _("Failed to open file '%s': %s"),
546                   utf8_filename ? utf8_filename : "???",
547                   g_strerror (errno));
548      g_free (utf8_filename);
549
550      return FALSE;
551    }
552
553  /* I don't think this will ever fail, aside from ENOMEM, but. */
554  if (fstat (fd, &stat_buf) < 0)
555    {
556      gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
557                                                 NULL, NULL, NULL);
558      close (fd);
559      g_set_error (error,
560                   G_FILE_ERROR,
561                   g_file_error_from_errno (errno),
562                   _("Failed to get attributes of file '%s': fstat() failed: %s"),
563                   utf8_filename ? utf8_filename : "???",
564                   g_strerror (errno));
565      g_free (utf8_filename);
566
567      return FALSE;
568    }
569
570  if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
571    {
572      return get_contents_regfile (filename,
573                                   &stat_buf,
574                                   fd,
575                                   contents,
576                                   length,
577                                   error);
578    }
579  else
580    {
581      FILE *f;
582
583      f = fdopen (fd, "r");
584     
585      if (f == NULL)
586        {
587          gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
588                                                     NULL, NULL, NULL);
589
590          g_set_error (error,
591                       G_FILE_ERROR,
592                       g_file_error_from_errno (errno),
593                       _("Failed to open file '%s': fdopen() failed: %s"),
594                       utf8_filename ? utf8_filename : "???",
595                       g_strerror (errno));
596          g_free (utf8_filename);
597
598          return FALSE;
599        }
600 
601      return get_contents_stdio (filename, f, contents, length, error);
602    }
603}
604
605#else  /* G_OS_WIN32 */
606
607static gboolean
608get_contents_win32 (const gchar *filename,
609                    gchar      **contents,
610                    gsize       *length,
611                    GError     **error)
612{
613  FILE *f;
614
615  /* I guess you want binary mode; maybe you want text sometimes? */
616  f = fopen (filename, "rb");
617
618  if (f == NULL)
619    {
620      gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
621                                                 NULL, NULL, NULL);
622     
623      g_set_error (error,
624                   G_FILE_ERROR,
625                   g_file_error_from_errno (errno),
626                   _("Failed to open file '%s': %s"),
627                   utf8_filename ? utf8_filename : "???",
628                   g_strerror (errno));
629      g_free (utf8_filename);
630
631      return FALSE;
632    }
633 
634  return get_contents_stdio (filename, f, contents, length, error);
635}
636
637#endif
638
639/**
640 * g_file_get_contents:
641 * @filename: a file to read contents from
642 * @contents: location to store an allocated string
643 * @length: location to store length in bytes of the contents
644 * @error: return location for a #GError
645 *
646 * Reads an entire file into allocated memory, with good error
647 * checking. If @error is set, %FALSE is returned, and @contents is set
648 * to %NULL. If %TRUE is returned, @error will not be set, and @contents
649 * will be set to the file contents.  The string stored in @contents
650 * will be nul-terminated, so for text files you can pass %NULL for the
651 * @length argument.  The error domain is #G_FILE_ERROR. Possible
652 * error codes are those in the #GFileError enumeration.
653 *
654 * Return value: %TRUE on success, %FALSE if error is set
655 **/
656gboolean
657g_file_get_contents (const gchar *filename,
658                     gchar      **contents,
659                     gsize       *length,
660                     GError     **error)
661
662  g_return_val_if_fail (filename != NULL, FALSE);
663  g_return_val_if_fail (contents != NULL, FALSE);
664
665  *contents = NULL;
666  if (length)
667    *length = 0;
668
669#ifdef G_OS_WIN32
670  return get_contents_win32 (filename, contents, length, error);
671#else
672  return get_contents_posix (filename, contents, length, error);
673#endif
674}
675
676/*
677 * mkstemp() implementation is from the GNU C library.
678 * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
679 */
680/**
681 * g_mkstemp:
682 * @tmpl: template filename
683 *
684 * Opens a temporary file. See the mkstemp() documentation
685 * on most UNIX-like systems. This is a portability wrapper, which simply calls
686 * mkstemp() on systems that have it, and implements
687 * it in GLib otherwise.
688 *
689 * The parameter is a string that should match the rules for
690 * mkstemp(), i.e. end in "XXXXXX". The X string will
691 * be modified to form the name of a file that didn't exist.
692 *
693 * Return value: A file handle (as from open()) to the file
694 * opened for reading and writing. The file is opened in binary mode
695 * on platforms where there is a difference. The file handle should be
696 * closed with close(). In case of errors, -1 is returned.
697 */
698gint
699g_mkstemp (gchar *tmpl)
700{
701#ifdef HAVE_MKSTEMP
702  return mkstemp (tmpl);
703#else
704  int len;
705  char *XXXXXX;
706  int count, fd;
707  static const char letters[] =
708    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
709  static const int NLETTERS = sizeof (letters) - 1;
710  glong value;
711  GTimeVal tv;
712  static int counter = 0;
713
714  len = strlen (tmpl);
715  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
716    return -1;
717
718  /* This is where the Xs start.  */
719  XXXXXX = &tmpl[len - 6];
720
721  /* Get some more or less random data.  */
722  g_get_current_time (&tv);
723  value = (tv.tv_usec ^ tv.tv_sec) + counter++;
724
725  for (count = 0; count < 100; value += 7777, ++count)
726    {
727      glong v = value;
728
729      /* Fill in the random bits.  */
730      XXXXXX[0] = letters[v % NLETTERS];
731      v /= NLETTERS;
732      XXXXXX[1] = letters[v % NLETTERS];
733      v /= NLETTERS;
734      XXXXXX[2] = letters[v % NLETTERS];
735      v /= NLETTERS;
736      XXXXXX[3] = letters[v % NLETTERS];
737      v /= NLETTERS;
738      XXXXXX[4] = letters[v % NLETTERS];
739      v /= NLETTERS;
740      XXXXXX[5] = letters[v % NLETTERS];
741
742      fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
743
744      if (fd >= 0)
745        return fd;
746      else if (errno != EEXIST)
747        /* Any other error will apply also to other names we might
748         *  try, and there are 2^32 or so of them, so give up now.
749         */
750        return -1;
751    }
752
753  /* We got out of the loop because we ran out of combinations to try.  */
754  return -1;
755#endif
756}
757
758/**
759 * g_file_open_tmp:
760 * @tmpl: Template for file name, as in g_mkstemp(), basename only
761 * @name_used: location to store actual name used
762 * @error: return location for a #GError
763 *
764 * Opens a file for writing in the preferred directory for temporary
765 * files (as returned by g_get_tmp_dir()).
766 *
767 * @tmpl should be a string ending with six 'X' characters, as the
768 * parameter to g_mkstemp() (or mkstemp()).
769 * However, unlike these functions, the template should only be a
770 * basename, no directory components are allowed. If template is %NULL,
771 * a default template is used.
772 *
773 * Note that in contrast to g_mkstemp() (and mkstemp())
774 * @tmpl is not modified, and might thus be a read-only literal string.
775 *
776 * The actual name used is returned in @name_used if non-%NULL. This
777 * string should be freed with g_free() when not needed any longer.
778 *
779 * Return value: A file handle (as from open()) to
780 * the file opened for reading and writing. The file is opened in binary
781 * mode on platforms where there is a difference. The file handle should be
782 * closed with close(). In case of errors, -1 is returned
783 * and @error will be set.
784 **/
785gint
786g_file_open_tmp (const gchar *tmpl,
787                 gchar      **name_used,
788                 GError     **error)
789{
790  int retval;
791  const char *tmpdir;
792  char *sep;
793  char *fulltemplate;
794  const char *slash;
795
796  if (tmpl == NULL)
797    tmpl = ".XXXXXX";
798
799  if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
800#ifdef G_OS_WIN32
801      || (strchr (tmpl, '/') != NULL && (slash = "/"))
802#endif
803      )
804    {
805      char c[2];
806      c[0] = *slash;
807      c[1] = '\0';
808
809      g_set_error (error,
810                   G_FILE_ERROR,
811                   G_FILE_ERROR_FAILED,
812                   _("Template '%s' invalid, should not contain a '%s'"),
813                   tmpl, c);
814
815      return -1;
816    }
817 
818  if (strlen (tmpl) < 6 ||
819      strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
820    {
821      g_set_error (error,
822                   G_FILE_ERROR,
823                   G_FILE_ERROR_FAILED,
824                   _("Template '%s' doesn't end with XXXXXX"),
825                   tmpl);
826      return -1;
827    }
828
829  tmpdir = g_get_tmp_dir ();
830
831  if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
832    sep = "";
833  else
834    sep = G_DIR_SEPARATOR_S;
835
836  fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
837
838  retval = g_mkstemp (fulltemplate);
839
840  if (retval == -1)
841    {
842      g_set_error (error,
843                   G_FILE_ERROR,
844                   g_file_error_from_errno (errno),
845                   _("Failed to create file '%s': %s"),
846                   fulltemplate, g_strerror (errno));
847      g_free (fulltemplate);
848      return -1;
849    }
850
851  if (name_used)
852    *name_used = fulltemplate;
853  else
854    g_free (fulltemplate);
855
856  return retval;
857}
858
859static gchar *
860g_build_pathv (const gchar *separator,
861               const gchar *first_element,
862               va_list      args)
863{
864  GString *result;
865  gint separator_len = strlen (separator);
866  gboolean is_first = TRUE;
867  gboolean have_leading = FALSE;
868  const gchar *single_element = NULL;
869  const gchar *next_element;
870  const gchar *last_trailing = NULL;
871
872  result = g_string_new (NULL);
873
874  next_element = first_element;
875
876  while (TRUE)
877    {
878      const gchar *element;
879      const gchar *start;
880      const gchar *end;
881
882      if (next_element)
883        {
884          element = next_element;
885          next_element = va_arg (args, gchar *);
886        }
887      else
888        break;
889
890      /* Ignore empty elements */
891      if (!*element)
892        continue;
893     
894      start = element;
895
896      if (separator_len)
897        {
898          while (start &&
899                 strncmp (start, separator, separator_len) == 0)
900            start += separator_len;
901        }
902
903      end = start + strlen (start);
904     
905      if (separator_len)
906        {
907          while (end >= start + separator_len &&
908                 strncmp (end - separator_len, separator, separator_len) == 0)
909            end -= separator_len;
910         
911          last_trailing = end;
912          while (last_trailing >= element + separator_len &&
913                 strncmp (last_trailing - separator_len, separator, separator_len) == 0)
914            last_trailing -= separator_len;
915
916          if (!have_leading)
917            {
918              /* If the leading and trailing separator strings are in the
919               * same element and overlap, the result is exactly that element
920               */
921              if (last_trailing <= start)
922                single_element = element;
923                 
924              g_string_append_len (result, element, start - element);
925              have_leading = TRUE;
926            }
927          else
928            single_element = NULL;
929        }
930
931      if (end == start)
932        continue;
933
934      if (!is_first)
935        g_string_append (result, separator);
936     
937      g_string_append_len (result, start, end - start);
938      is_first = FALSE;
939    }
940
941  if (single_element)
942    {
943      g_string_free (result, TRUE);
944      return g_strdup (single_element);
945    }
946  else
947    {
948      if (last_trailing)
949        g_string_append (result, last_trailing);
950 
951      return g_string_free (result, FALSE);
952    }
953}
954
955/**
956 * g_build_path:
957 * @separator: a string used to separator the elements of the path.
958 * @first_element: the first element in the path
959 * @Varargs: remaining elements in path, terminated by %NULL
960 *
961 * Creates a path from a series of elements using @separator as the
962 * separator between elements. At the boundary between two elements,
963 * any trailing occurrences of separator in the first element, or
964 * leading occurrences of separator in the second element are removed
965 * and exactly one copy of the separator is inserted.
966 *
967 * Empty elements are ignored.
968 *
969 * The number of leading copies of the separator on the result is
970 * the same as the number of leading copies of the separator on
971 * the first non-empty element.
972 *
973 * The number of trailing copies of the separator on the result is
974 * the same as the number of trailing copies of the separator on
975 * the last non-empty element. (Determination of the number of
976 * trailing copies is done without stripping leading copies, so
977 * if the separator is <literal>ABA</literal>, <literal>ABABA</literal>
978 * has 1 trailing copy.)
979 *
980 * However, if there is only a single non-empty element, and there
981 * are no characters in that element not part of the leading or
982 * trailing separators, then the result is exactly the original value
983 * of that element.
984 *
985 * Other than for determination of the number of leading and trailing
986 * copies of the separator, elements consisting only of copies
987 * of the separator are ignored.
988 *
989 * Return value: a newly-allocated string that must be freed with g_free().
990 **/
991gchar *
992g_build_path (const gchar *separator,
993              const gchar *first_element,
994              ...)
995{
996  gchar *str;
997  va_list args;
998
999  g_return_val_if_fail (separator != NULL, NULL);
1000
1001  va_start (args, first_element);
1002  str = g_build_pathv (separator, first_element, args);
1003  va_end (args);
1004
1005  return str;
1006}
1007
1008/**
1009 * g_build_filename:
1010 * @first_element: the first element in the path
1011 * @Varargs: remaining elements in path, terminated by %NULL
1012 *
1013 * Creates a filename from a series of elements using the correct
1014 * separator for filenames.
1015 *
1016 * On Unix, this function behaves identically to <literal>g_build_path
1017 * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
1018 *
1019 * On Windows, it takes into account that either the backslash
1020 * (<literal>\</literal> or slash (<literal>/</literal>) can be used
1021 * as separator in filenames, but otherwise behaves as on Unix. When
1022 * file pathname separators need to be inserted, the one that last
1023 * previously occurred in the parameters (reading from left to right)
1024 * is used.
1025 *
1026 * No attempt is made to force the resulting filename to be an absolute
1027 * path. If the first element is a relative path, the result will
1028 * be a relative path.
1029 *
1030 * Return value: a newly-allocated string that must be freed with g_free().
1031 **/
1032gchar *
1033g_build_filename (const gchar *first_element,
1034                  ...)
1035{
1036#ifndef G_OS_WIN32
1037  gchar *str;
1038  va_list args;
1039
1040  va_start (args, first_element);
1041  str = g_build_pathv (G_DIR_SEPARATOR_S, first_element, args);
1042  va_end (args);
1043
1044  return str;
1045#else
1046  /* Code copied from g_build_pathv(), and modifed to use two
1047   * alternative single-character separators.
1048   */
1049  va_list args;
1050  GString *result;
1051  gboolean is_first = TRUE;
1052  gboolean have_leading = FALSE;
1053  const gchar *single_element = NULL;
1054  const gchar *next_element;
1055  const gchar *last_trailing = NULL;
1056  gchar current_separator = '\\';
1057
1058  va_start (args, first_element);
1059
1060  result = g_string_new (NULL);
1061
1062  next_element = first_element;
1063
1064  while (TRUE)
1065    {
1066      const gchar *element;
1067      const gchar *start;
1068      const gchar *end;
1069
1070      if (next_element)
1071        {
1072          element = next_element;
1073          next_element = va_arg (args, gchar *);
1074        }
1075      else
1076        break;
1077
1078      /* Ignore empty elements */
1079      if (!*element)
1080        continue;
1081     
1082      start = element;
1083
1084      if (TRUE)
1085        {
1086          while (start &&
1087                 (*start == '\\' || *start == '/'))
1088            {
1089              current_separator = *start;
1090              start++;
1091            }
1092        }
1093
1094      end = start + strlen (start);
1095     
1096      if (TRUE)
1097        {
1098          while (end >= start + 1 &&
1099                 (end[-1] == '\\' || end[-1] == '/'))
1100            {
1101              current_separator = end[-1];
1102              end--;
1103            }
1104         
1105          last_trailing = end;
1106          while (last_trailing >= element + 1 &&
1107                 (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
1108            last_trailing--;
1109
1110          if (!have_leading)
1111            {
1112              /* If the leading and trailing separator strings are in the
1113               * same element and overlap, the result is exactly that element
1114               */
1115              if (last_trailing <= start)
1116                single_element = element;
1117                 
1118              g_string_append_len (result, element, start - element);
1119              have_leading = TRUE;
1120            }
1121          else
1122            single_element = NULL;
1123        }
1124
1125      if (end == start)
1126        continue;
1127
1128      if (!is_first)
1129        g_string_append_len (result, &current_separator, 1);
1130     
1131      g_string_append_len (result, start, end - start);
1132      is_first = FALSE;
1133    }
1134
1135  va_end (args);
1136
1137  if (single_element)
1138    {
1139      g_string_free (result, TRUE);
1140      return g_strdup (single_element);
1141    }
1142  else
1143    {
1144      if (last_trailing)
1145        g_string_append (result, last_trailing);
1146 
1147      return g_string_free (result, FALSE);
1148    }
1149#endif
1150}
1151
1152/**
1153 * g_file_read_link:
1154 * @filename: the symbolic link
1155 * @error: return location for a #GError
1156 *
1157 * Reads the contents of the symbolic link @filename like the POSIX readlink() function.
1158 * The returned string is in the encoding used for filenames. Use g_filename_to_utf8() to
1159 * convert it to UTF-8.
1160 *
1161 * Returns: A newly allocated string with the contents of the symbolic link,
1162 *          or %NULL if an error occurred.
1163 *
1164 * Since: 2.4
1165 */
1166gchar *
1167g_file_read_link (const gchar *filename,
1168                  GError     **error)
1169{
1170#ifdef HAVE_READLINK
1171  gchar *buffer;
1172  guint size;
1173  gint read_size;   
1174 
1175  size = 256;
1176  buffer = g_malloc (size);
1177 
1178  while (TRUE)
1179    {
1180      read_size = readlink (filename, buffer, size);
1181      if (read_size < 0) {
1182        gchar *utf8_filename = g_filename_to_utf8 (filename, -1,
1183                                                   NULL, NULL, NULL);
1184        g_free (buffer);
1185        g_set_error (error,
1186                     G_FILE_ERROR,
1187                     g_file_error_from_errno (errno),
1188                     _("Failed to read the symbolic link '%s': %s"),
1189                     utf8_filename ? utf8_filename : "???",
1190                     g_strerror (errno));
1191        g_free (utf8_filename);
1192       
1193        return NULL;
1194      }
1195   
1196      if (read_size < size)
1197        {
1198          buffer[read_size] = 0;
1199          return buffer;
1200        }
1201     
1202      size *= 2;
1203      buffer = g_realloc (buffer, size);
1204    }
1205#else
1206  g_set_error (error,
1207               G_FILE_ERROR,
1208               G_FILE_ERROR_INVAL,
1209               _("Symbolic links not supported"));
1210       
1211  return NULL;
1212#endif
1213}
Note: See TracBrowser for help on using the repository browser.