add Berkeley specific header; written by Sam Leffler
[unix-history] / usr / src / lib / libc / gen / getcwd.c
index 448fb84..3e2c41f 100644 (file)
@@ -1,4 +1,12 @@
-/*     @(#)getcwd.c    4.7     (Berkeley)      %G%     */
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getcwd.c   5.2 (Berkeley) %G%";
+#endif LIBC_SCCS and not lint
 
 /*
  * getwd() returns the pathname of the current working directory. On error
 
 /*
  * getwd() returns the pathname of the current working directory. On error
@@ -8,12 +16,9 @@
 #include <sys/stat.h>
 #include <sys/dir.h>
 
 #include <sys/stat.h>
 #include <sys/dir.h>
 
-#define CURDIR         "."
 #define GETWDERR(s)    strcpy(pathname, (s));
 #define GETWDERR(s)    strcpy(pathname, (s));
-#define PARENTDIR      ".."
-#define PATHSEP                "/"
-#define ROOTDIR                "/"
 
 
+char *strcpy();
 static int pathsize;                   /* pathname length */
 
 char *
 static int pathsize;                   /* pathname length */
 
 char *
@@ -22,33 +27,43 @@ getwd(pathname)
 {
        char pathbuf[MAXPATHLEN];               /* temporary pathname buffer */
        char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
 {
        char pathbuf[MAXPATHLEN];               /* temporary pathname buffer */
        char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
+       char curdir[MAXPATHLEN];        /* current directory buffer */
+       char *dptr = curdir;            /* directory pointer */
        char *prepend();                /* prepend dirname to pathname */
        char *prepend();                /* prepend dirname to pathname */
-       dev_t rdev;                     /* root device number */
+       dev_t cdev, rdev;               /* current & root device number */
+       ino_t cino, rino;               /* current & root inode number */
        DIR *dirp;                      /* directory stream */
        DIR *dirp;                      /* directory stream */
-       ino_t rino;                     /* root inode number */
        struct direct *dir;             /* directory entry struct */
        struct direct *dir;             /* directory entry struct */
-       struct stat d ,dd;              /* file status struct */
+       struct stat ddd;              /* file status struct */
 
        pathsize = 0;
        *pnptr = '\0';
 
        pathsize = 0;
        *pnptr = '\0';
-       stat(ROOTDIR, &d);
+       if (stat("/", &d) < 0) {
+               GETWDERR("getwd: can't stat /");
+               return (NULL);
+       }
        rdev = d.st_dev;
        rino = d.st_ino;
        rdev = d.st_dev;
        rino = d.st_ino;
+       strcpy(dptr, "./");
+       dptr += 2;
+       if (stat(curdir, &d) < 0) {
+               GETWDERR("getwd: can't stat .");
+               return (NULL);
+       }
        for (;;) {
        for (;;) {
-               stat(CURDIR, &d);
                if (d.st_ino == rino && d.st_dev == rdev)
                        break;          /* reached root directory */
                if (d.st_ino == rino && d.st_dev == rdev)
                        break;          /* reached root directory */
-               if ((dirp = opendir(PARENTDIR)) == NULL) {
+               cino = d.st_ino;
+               cdev = d.st_dev;
+               strcpy(dptr, "../");
+               dptr += 3;
+               if ((dirp = opendir(curdir)) == NULL) {
                        GETWDERR("getwd: can't open ..");
                        GETWDERR("getwd: can't open ..");
-                       goto fail;
-               }
-               if (chdir(PARENTDIR) < 0) {
-                       GETWDERR("getwd: can't chdir to ..");
-                       goto fail;
+                       return (NULL);
                }
                }
-               fstat(dirp->dd_fd, &dd);
-               if (d.st_dev == dd.st_dev) {
-                       if (d.st_ino == dd.st_ino) {
+               fstat(dirp->dd_fd, &d);
+               if (cdev == d.st_dev) {
+                       if (cino == d.st_ino) {
                                /* reached root directory */
                                closedir(dirp);
                                break;
                                /* reached root directory */
                                closedir(dirp);
                                break;
@@ -57,35 +72,27 @@ getwd(pathname)
                                if ((dir = readdir(dirp)) == NULL) {
                                        closedir(dirp);
                                        GETWDERR("getwd: read error in ..");
                                if ((dir = readdir(dirp)) == NULL) {
                                        closedir(dirp);
                                        GETWDERR("getwd: read error in ..");
-                                       goto fail;
+                                       return (NULL);
                                }
                                }
-                       } while (dir->d_ino != d.st_ino);
+                       } while (dir->d_ino != cino);
                } else
                        do {
                } else
                        do {
-                               if((dir = readdir(dirp)) == NULL) {
+                               if ((dir = readdir(dirp)) == NULL) {
                                        closedir(dirp);
                                        GETWDERR("getwd: read error in ..");
                                        closedir(dirp);
                                        GETWDERR("getwd: read error in ..");
-                                       goto fail;
+                                       return (NULL);
                                }
                                }
-                               stat(dir->d_name, &dd);
-                       } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
+                               strcpy(dptr, dir->d_name);
+                               lstat(curdir, &dd);
+                       } while(dd.st_ino != cino || dd.st_dev != cdev);
                closedir(dirp);
                closedir(dirp);
-               pnptr = prepend(PATHSEP, prepend(dir->d_name, pnptr));
+               pnptr = prepend("/", prepend(dir->d_name, pnptr));
        }
        if (*pnptr == '\0')             /* current dir == root dir */
        }
        if (*pnptr == '\0')             /* current dir == root dir */
-               strcpy(pathname, ROOTDIR);
-       else {
+               strcpy(pathname, "/");
+       else
                strcpy(pathname, pnptr);
                strcpy(pathname, pnptr);
-               if (chdir(pnptr) < 0) {
-                       GETWDERR("getwd: can't change back to .");
-                       return (NULL);
-               }
-       }
        return (pathname);
        return (pathname);
-
-fail:
-       chdir(prepend(CURDIR, pnptr));
-       return (NULL);
 }
 
 /*
 }
 
 /*