00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "db_config.h"
00039
00040 #ifndef NO_SYSTEM_INCLUDES
00041 #include <sys/types.h>
00042 #include <sys/stat.h>
00043
00044 #if HAVE_DIRENT_H
00045 # include <dirent.h>
00046 # define NAMLEN(dirent) strlen((dirent)->d_name)
00047 #else
00048 # define dirent direct
00049 # define NAMLEN(dirent) (dirent)->d_namlen
00050 # if HAVE_SYS_NDIR_H
00051 # include <sys/ndir.h>
00052 # endif
00053 # if HAVE_SYS_DIR_H
00054 # include <sys/dir.h>
00055 # endif
00056 # if HAVE_NDIR_H
00057 # include <ndir.h>
00058 # endif
00059 #endif
00060
00061 #include <stdio.h>
00062 #include <stdlib.h>
00063 #include <string.h>
00064 #include <unistd.h>
00065 #endif
00066
00067 #include "db_int.h"
00068
00069 #define ISDOT(dp) \
00070 (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \
00071 (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
00072
00073 #ifndef dirfd
00074 #define dirfd(dirp) ((dirp)->dd_fd)
00075 #endif
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 char *
00086 getcwd(pt, size)
00087 char *pt;
00088 size_t size;
00089 {
00090 register struct dirent *dp;
00091 register DIR *dir;
00092 register dev_t dev;
00093 register ino_t ino;
00094 register int first;
00095 register char *bpt, *bup;
00096 struct stat s;
00097 dev_t root_dev;
00098 ino_t root_ino;
00099 size_t ptsize, upsize;
00100 int ret, save_errno;
00101 char *ept, *eup, *up;
00102
00103
00104
00105
00106
00107
00108 if (pt) {
00109 ptsize = 0;
00110 if (!size) {
00111 __os_set_errno(EINVAL);
00112 return (NULL);
00113 }
00114 if (size == 1) {
00115 __os_set_errno(ERANGE);
00116 return (NULL);
00117 }
00118 ept = pt + size;
00119 } else {
00120 if ((ret =
00121 __os_malloc(NULL, ptsize = 1024 - 4, &pt)) != 0) {
00122 __os_set_errno(ret);
00123 return (NULL);
00124 }
00125 ept = pt + ptsize;
00126 }
00127 bpt = ept - 1;
00128 *bpt = '\0';
00129
00130
00131
00132
00133
00134
00135 if ((ret = __os_malloc(NULL, upsize = 1024 - 4, &up)) != 0)
00136 goto err;
00137 eup = up + 1024;
00138 bup = up;
00139 up[0] = '.';
00140 up[1] = '\0';
00141
00142
00143 if (stat("/", &s))
00144 goto err;
00145 root_dev = s.st_dev;
00146 root_ino = s.st_ino;
00147
00148 __os_set_errno(0);
00149
00150 for (first = 1;; first = 0) {
00151
00152 if (lstat(up, &s))
00153 goto err;
00154
00155
00156 ino = s.st_ino;
00157 dev = s.st_dev;
00158
00159
00160 if (root_dev == dev && root_ino == ino) {
00161 *--bpt = PATH_SEPARATOR[0];
00162
00163
00164
00165
00166
00167 bcopy(bpt, pt, ept - bpt);
00168 __os_free(NULL, up);
00169 return (pt);
00170 }
00171
00172
00173
00174
00175
00176
00177 if (bup + 3 + MAXNAMLEN + 1 >= eup) {
00178 if (__os_realloc(NULL, upsize *= 2, &up) != 0)
00179 goto err;
00180 bup = up;
00181 eup = up + upsize;
00182 }
00183 *bup++ = '.';
00184 *bup++ = '.';
00185 *bup = '\0';
00186
00187
00188 if (!(dir = opendir(up)) || fstat(dirfd(dir), &s))
00189 goto err;
00190
00191
00192 *bup++ = PATH_SEPARATOR[0];
00193
00194
00195
00196
00197
00198
00199 save_errno = 0;
00200 if (s.st_dev == dev) {
00201 for (;;) {
00202 if (!(dp = readdir(dir)))
00203 goto notfound;
00204 if (dp->d_fileno == ino)
00205 break;
00206 }
00207 } else
00208 for (;;) {
00209 if (!(dp = readdir(dir)))
00210 goto notfound;
00211 if (ISDOT(dp))
00212 continue;
00213 bcopy(dp->d_name, bup, dp->d_namlen + 1);
00214
00215
00216 if (lstat(up, &s)) {
00217 if (save_errno == 0)
00218 save_errno = __os_get_errno();
00219 __os_set_errno(0);
00220 continue;
00221 }
00222 if (s.st_dev == dev && s.st_ino == ino)
00223 break;
00224 }
00225
00226
00227
00228
00229
00230 if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) {
00231 size_t len, off;
00232
00233 if (!ptsize) {
00234 __os_set_errno(ERANGE);
00235 goto err;
00236 }
00237 off = bpt - pt;
00238 len = ept - bpt;
00239 if (__os_realloc(NULL, ptsize *= 2, &pt) != 0)
00240 goto err;
00241 bpt = pt + off;
00242 ept = pt + ptsize;
00243 bcopy(bpt, ept - len, len);
00244 bpt = ept - len;
00245 }
00246 if (!first)
00247 *--bpt = PATH_SEPARATOR[0];
00248 bpt -= dp->d_namlen;
00249 bcopy(dp->d_name, bpt, dp->d_namlen);
00250 (void)closedir(dir);
00251
00252
00253 *bup = '\0';
00254 }
00255
00256 notfound:
00257
00258
00259
00260
00261
00262 if (__os_get_errno_ret_zero() == 0)
00263 __os_set_errno(save_errno == 0 ? ENOENT : save_errno);
00264
00265 err:
00266 if (ptsize)
00267 __os_free(NULL, pt);
00268 __os_free(NULL, up);
00269 return (NULL);
00270 }