-/* getcwd.c -- stolen from the GNU C library and modified to work with bash. */
+/* getcwd.c -- get pathname of current directory */
/* Copyright (C) 1991 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ This file is part of GNU Bash, the Bourne Again SHell.
- The GNU C Library is distributed in the hope that it will be useful,
+ Bash is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc.,
- 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+ You should have received a copy of the GNU General Public License
+ along with Bash. If not, see <http://www.gnu.org/licenses/>.
+*/
#include <config.h>
#if !defined (HAVE_GETCWD)
+#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
+ #pragma alloca
+#endif /* _AIX && RISC6000 && !__GNUC__ */
+
+#if defined (__QNX__)
+# undef HAVE_LSTAT
+#endif
+
#include <bashtypes.h>
#include <errno.h>
#include <bashansi.h>
+#include <xmalloc.h>
+
#if !defined (errno)
extern int errno;
#endif /* !errno */
-#if defined (__STDC__)
-# define CONST const
-# define PTR void *
-#else /* !__STDC__ */
-# define CONST
-# define PTR char *
-#endif /* !__STDC__ */
-
-#if !defined (PATH_MAX)
-# if defined (MAXPATHLEN)
-# define PATH_MAX MAXPATHLEN
-# else /* !MAXPATHLEN */
-# define PATH_MAX 1024
-# endif /* !MAXPATHLEN */
-#endif /* !PATH_MAX */
-
#if !defined (HAVE_LSTAT)
# define lstat stat
#endif
# define NULL 0
#endif
+/* If the d_fileno member of a struct dirent doesn't return anything useful,
+ we need to check inode number equivalence the hard way. Return 1 if
+ the inode corresponding to PATH/DIR is identical to THISINO. */
+#if defined (BROKEN_DIRENT_D_INO)
+static int
+_path_checkino (dotp, name, thisino)
+ char *dotp;
+ char *name;
+ ino_t thisino;
+{
+ char *fullpath;
+ int r, e;
+ struct stat st;
+
+ e = errno;
+ fullpath = sh_makepath (dotp, name, MP_RMDOT);
+ if (stat (fullpath, &st) < 0)
+ {
+ errno = e;
+ return 0;
+ }
+ free (fullpath);
+ errno = e;
+ return (st.st_ino == thisino);
+}
+#endif
+
/* Get the pathname of the current working directory,
and put it in SIZE bytes of BUF. Returns NULL if the
directory couldn't be determined or SIZE was too small.
size_t size;
#endif /* !__STDC__ */
{
- static CONST char dots[]
+ static const char dots[]
= "../../../../../../../../../../../../../../../../../../../../../../../\
../../../../../../../../../../../../../../../../../../../../../../../../../../\
../../../../../../../../../../../../../../../../../../../../../../../../../..";
- CONST char *dotp, *dotlist;
+ const char *dotp, *dotlist;
size_t dotsize;
dev_t rootdev, thisdev;
ino_t rootino, thisino;
}
else
{
- new = (char *)realloc ((PTR) dotlist, dotsize * 2 + 1);
+ new = (char *)realloc ((PTR_T) dotlist, dotsize * 2 + 1);
if (new == NULL)
goto lose;
}
(d->d_name[1] == '\0' ||
(d->d_name[1] == '.' && d->d_name[2] == '\0')))
continue;
+#if !defined (BROKEN_DIRENT_D_INO)
if (mount_point || d->d_fileno == thisino)
+#else
+ if (mount_point || _path_checkino (dotp, d->d_name, thisino))
+#endif
{
char *name;
}
else
{
- new = (char *)realloc ((PTR) pathbuf, (pathsize * 2));
+ new = (char *)realloc ((PTR_T) pathbuf, (pathsize * 2));
if (!new)
goto lose;
pathp = new + space;
*--pathp = '/';
if (dotlist != dots)
- free ((PTR) dotlist);
+ free ((PTR_T) dotlist);
{
size_t len = pathbuf + pathsize - pathp;
+ if (buf == NULL && size <= 0)
+ size = len;
+
+ if ((size_t) size < len)
+ {
+ errno = ERANGE;
+ goto lose2;
+ }
if (buf == NULL)
{
- if (len < (size_t) size)
- len = size;
- buf = (char *) malloc (len);
+ buf = (char *) malloc (size);
if (buf == NULL)
goto lose2;
}
- else if ((size_t) size < len)
- {
- errno = ERANGE;
- goto lose2;
- }
- (void) memcpy((PTR) buf, (PTR) pathp, len);
+
+ (void) memcpy((PTR_T) buf, (PTR_T) pathp, len);
}
if (pathbuf != path)
if ((dotlist != dots) && dotlist)
{
int e = errno;
- free ((PTR) dotlist);
+ free ((PTR_T) dotlist);
errno = e;
}
if ((pathbuf != path) && pathbuf)
{
int e = errno;
- free ((PTR) pathbuf);
+ free ((PTR_T) pathbuf);
errno = e;
}
return ((char *)NULL);