]>
git.ipfire.org Git - thirdparty/bash.git/blob - getcwd.c
1 /* getcwd.c -- stolen from the GNU C library and modified to work with bash. */
3 /* Copyright (C) 1991 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library 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.
11 The GNU C Library 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 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If
18 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 Cambridge, MA 02139, USA. */
23 #if !defined (HAVE_GETCWD)
25 #include "bashtypes.h"
28 #if defined (HAVE_LIMITS_H)
32 #if defined (HAVE_UNISTD_H)
37 #include "posixstat.h"
47 #if defined (__STDC__)
53 #endif /* !__STDC__ */
55 #if !defined (PATH_MAX)
56 # if defined (MAXPATHLEN)
57 # define PATH_MAX MAXPATHLEN
58 # else /* !MAXPATHLEN */
59 # define PATH_MAX 1024
60 # endif /* !MAXPATHLEN */
61 #endif /* !PATH_MAX */
63 #if !defined (HAVE_LSTAT)
67 /* Get the pathname of the current working directory,
68 and put it in SIZE bytes of BUF. Returns NULL if the
69 directory couldn't be determined or SIZE was too small.
70 If successful, returns BUF. In GNU, if BUF is NULL,
71 an array is allocated with `malloc'; the array is SIZE
72 bytes long, unless SIZE <= 0, in which case it is as
74 #if defined (__STDC__)
76 getcwd (char *buf
, size_t size
)
82 #endif /* !__STDC__ */
84 static CONST
char dots
[]
85 = "../../../../../../../../../../../../../../../../../../../../../../../\
86 ../../../../../../../../../../../../../../../../../../../../../../../../../../\
87 ../../../../../../../../../../../../../../../../../../../../../../../../../..";
88 CONST
char *dotp
, *dotlist
;
90 dev_t rootdev
, thisdev
;
91 ino_t rootino
, thisino
;
92 char path
[PATH_MAX
+ 1];
98 if (buf
!= NULL
&& size
== 0)
101 return ((char *)NULL
);
104 pathsize
= sizeof (path
);
105 pathp
= &path
[pathsize
];
109 if (stat (".", &st
) < 0)
110 return ((char *)NULL
);
114 if (stat ("/", &st
) < 0)
115 return ((char *)NULL
);
119 dotsize
= sizeof (dots
) - 1;
120 dotp
= &dots
[sizeof (dots
)];
122 while (!(thisdev
== rootdev
&& thisino
== rootino
))
124 register DIR *dirstream
;
125 register struct dirent
*d
;
131 /* Look at the parent directory. */
134 /* My, what a deep directory tree you have, Grandma. */
138 new = malloc (dotsize
* 2 + 1);
141 memcpy (new, dots
, dotsize
);
145 new = realloc ((PTR
) dotlist
, dotsize
* 2 + 1);
149 memcpy (&new[dotsize
], new, dotsize
);
150 dotp
= &new[dotsize
];
158 /* Figure out if this directory is a mount point. */
159 if (stat (dotp
, &st
) < 0)
163 mount_point
= dotdev
!= thisdev
;
165 /* Search for the last directory. */
166 dirstream
= opendir (dotp
);
167 if (dirstream
== NULL
)
169 while ((d
= readdir (dirstream
)) != NULL
)
171 if (d
->d_name
[0] == '.' &&
172 (d
->d_name
[1] == '\0' ||
173 (d
->d_name
[1] == '.' && d
->d_name
[2] == '\0')))
175 if (mount_point
|| d
->d_fileno
== thisino
)
179 namlen
= D_NAMLEN(d
);
181 alloca (dotlist
+ dotsize
- dotp
+ 1 + namlen
+ 1);
182 memcpy (name
, dotp
, dotlist
+ dotsize
- dotp
);
183 name
[dotlist
+ dotsize
- dotp
] = '/';
184 memcpy (&name
[dotlist
+ dotsize
- dotp
+ 1],
185 d
->d_name
, namlen
+ 1);
186 if (lstat (name
, &st
) < 0)
189 (void) closedir (dirstream
);
193 if (st
.st_dev
== thisdev
&& st
.st_ino
== thisino
)
200 (void) closedir (dirstream
);
208 while ((space
= pathp
- pathbuf
) <= namlen
)
214 new = malloc (pathsize
* 2);
220 new = realloc ((PTR
) pathbuf
, (pathsize
* 2));
225 (void) memcpy (new + pathsize
+ space
, pathp
, pathsize
- space
);
226 pathp
= new + pathsize
+ space
;
232 (void) memcpy (pathp
, d
->d_name
, namlen
);
234 (void) closedir (dirstream
);
241 if (pathp
== &path
[sizeof(path
) - 1])
245 free ((PTR
) dotlist
);
248 size_t len
= pathbuf
+ pathsize
- pathp
;
251 if (len
< (size_t) size
)
253 buf
= (char *) malloc (len
);
257 else if ((size_t) size
< len
)
262 (void) memcpy((PTR
) buf
, (PTR
) pathp
, len
);
271 if ((dotlist
!= dots
) && dotlist
)
274 free ((PTR
) dotlist
);
279 if ((pathbuf
!= path
) && pathbuf
)
282 free ((PTR
) pathbuf
);
285 return ((char *)NULL
);
296 if (getcwd(b
, sizeof(b
)))
303 perror ("cwd: getcwd");
308 #endif /* !HAVE_GETCWD */