1/* xgetcwd.c -- return current directory with unlimited length 2 Copyright (C) 1992, 1996, 2000, 2003 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 2, or (at your option) 7 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, write to the Free Software Foundation, 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */ 19 20#if HAVE_CONFIG_H 21# include <config.h> 22#endif 23 24#include <stdlib.h> 25#include <stdio.h> 26#include <errno.h> 27#ifndef errno 28extern int errno; 29#endif 30 31#include <sys/types.h> 32#if HAVE_UNISTD_H 33# include <unistd.h> 34#endif 35 36#include "pathmax.h" 37 38#if HAVE_GETCWD 39# ifdef VMS 40 /* We want the directory in Unix syntax, not in VMS syntax. */ 41# define getcwd(Buf, Max) (getcwd) (Buf, Max, 0) 42# else 43# ifndef _FORTIFY_SOURCE 44char *getcwd (); 45# endif 46# endif 47#else 48char *getwd (); 49# define getcwd(Buf, Max) getwd (Buf) 50#endif 51 52#include "xalloc.h" 53 54/* Return the current directory, newly allocated, arbitrarily long. 55 Return NULL and set errno on error. */ 56 57char * 58xgetcwd () 59{ 60 char *ret; 61 unsigned path_max; 62 char buf[1024]; 63 64 errno = 0; 65 ret = getcwd (buf, sizeof (buf)); 66 if (ret != NULL) 67 return xstrdup (buf); 68 if (errno != ERANGE) 69 return NULL; 70 71 path_max = (unsigned) PATH_MAX; 72 path_max += 2; /* The getcwd docs say to do this. */ 73 74 for (;;) 75 { 76 char *cwd = (char *) xmalloc (path_max); 77 78 errno = 0; 79 ret = getcwd (cwd, path_max); 80 if (ret != NULL) 81 return ret; 82 if (errno != ERANGE) 83 { 84 int save_errno = errno; 85 free (cwd); 86 errno = save_errno; 87 return NULL; 88 } 89 90 free (cwd); 91 92 path_max += path_max / 16; 93 path_max += 32; 94 } 95} 96