0b1016c55d29bc3591d7c1d9b15b35d615373bff
[platform/upstream/gettext.git] / gnulib-local / lib / xgetcwd.c
1 /* xgetcwd.c -- return current directory with unlimited length
2    Copyright (C) 1992, 1996, 2000, 2003, 2005-2006 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17 /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
18
19 #include <config.h>
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include "pathmax.h"
28
29 #if HAVE_GETCWD
30 # ifdef VMS
31    /* We want the directory in Unix syntax, not in VMS syntax.  */
32 #  define getcwd(Buf, Max) (getcwd) (Buf, Max, 0)
33 # else
34 char *getcwd ();
35 # endif
36 #else
37 char *getwd ();
38 # define getcwd(Buf, Max) getwd (Buf)
39 #endif
40
41 #include "xalloc.h"
42
43 /* Return the current directory, newly allocated, arbitrarily long.
44    Return NULL and set errno on error. */
45
46 char *
47 xgetcwd ()
48 {
49   char *ret;
50   unsigned path_max;
51   char buf[1024];
52
53   errno = 0;
54   ret = getcwd (buf, sizeof (buf));
55   if (ret != NULL)
56     return xstrdup (buf);
57   if (errno != ERANGE)
58     return NULL;
59
60   path_max = (unsigned) PATH_MAX;
61   path_max += 2;                /* The getcwd docs say to do this. */
62
63   for (;;)
64     {
65       char *cwd = XNMALLOC (path_max, char);
66
67       errno = 0;
68       ret = getcwd (cwd, path_max);
69       if (ret != NULL)
70         return ret;
71       if (errno != ERANGE)
72         {
73           int save_errno = errno;
74           free (cwd);
75           errno = save_errno;
76           return NULL;
77         }
78
79       free (cwd);
80
81       path_max += path_max / 16;
82       path_max += 32;
83     }
84 }