summaryrefslogtreecommitdiff
path: root/dmake/unix/xenix/pwd/getcwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'dmake/unix/xenix/pwd/getcwd.c')
-rw-r--r--dmake/unix/xenix/pwd/getcwd.c231
1 files changed, 0 insertions, 231 deletions
diff --git a/dmake/unix/xenix/pwd/getcwd.c b/dmake/unix/xenix/pwd/getcwd.c
deleted file mode 100644
index 5c5b84711..000000000
--- a/dmake/unix/xenix/pwd/getcwd.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- getcwd -- get pathname of current working directory
-
- public-domain implementation
-
- last edit: 03-Nov-1990 Gwyn@BRL.MIL
-
- complies with the following standards:
- IEEE Std 1003.1-1988
- SVID Issue 3
- X/Open Portability Guide Issue 2 (when "XPG2" is defined)
- X/Open Portability Guide Issue 3
-
- This implementation of getcwd() can be used to replace the UNIX
- System V library routine (which uses popen() to capture the output of
- the "pwd" command). Once that is done, "pwd" can be reimplemented as
- just puts(getcwd((char*)0,0)), assuming "XPG2" is defined below.
-
- This implementation depends on every directory having entries for
- "." and "..". It also depends on the internals of the <dirent.h>
- data structures to some degree.
-
- I considered using chdir() to ascend the hierarchy, followed by a
- final chdir() to the path being returned by getcwd() to restore the
- location, but decided that error recovery was too difficult that way.
- The algorithm I settled on was inspired by my rewrite of the "pwd"
- utility, combined with the dotdots[] array trick from the SVR2 shell.
-*/
-#define XPG2 /* define to support obsolete XPG2-mandated feature */
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#ifdef M_XENIX
-# include <sys/ndir.h>
-# define dirent direct
-#else
-# include <dirent.h>
-#endif
-
-#include <errno.h>
-#include <string.h>
-
-typedef char *pointer; /* (void *) if you have it */
-
-extern void free();
-extern pointer malloc();
-extern int fstat(), stat();
-
-extern int errno; /* normally done by <errno.h> */
-
-#ifndef NULL
-#define NULL 0 /* amorphous null pointer constant */
-#endif
-
-#ifndef NAME_MAX
-#define NAME_MAX 255 /* maximum directory entry size */
-#endif
-
-
-char *
-getcwd( buf, size ) /* returns pointer to CWD pathname */
- char *buf; /* where to put name (NULL to malloc) */
- int size; /* size of buf[] or malloc()ed memory */
- {
- static char dotdots[] =
-"../../../../../../../../../../../../../../../../../../../../../../../../../..";
- char *dotdot; /* -> dotdots[.], right to left */
- DIR *dirp; /* -> parent directory stream */
- struct dirent *dir; /* -> directory entry */
- struct stat stat1,
- stat2; /* info from stat() */
- struct stat *d = &stat1; /* -> info about "." */
- struct stat *dd = &stat2; /* -> info about ".." */
- register char *buffer; /* local copy of buf, or malloc()ed */
- char *bufend; /* -> buffer[size] */
- register char *endp; /* -> end of reversed string */
- register char *dname; /* entry name ("" for root) */
- int serrno = errno; /* save entry errno */
-
- if ( buf != NULL && size <= 0
-#ifndef XPG2
- || buf == NULL
-#endif
- ) {
- errno = EINVAL; /* invalid argument */
- return NULL;
- }
-
- buffer = buf;
-#ifdef XPG2
- if ( buf == NULL /* wants us to malloc() the string */
- && (buffer = (char *) malloc( (unsigned) size )) == NULL
- /* XXX -- actually should probably not pay attention to "size" arg */
- ) {
- errno = ENOMEM; /* cannot malloc() specified size */
- return NULL;
- }
-#endif
-
- if ( stat( ".", dd ) != 0 ) /* prime the pump */
- goto error; /* errno already set */
-
- endp = buffer; /* initially, empty string */
- bufend = &buffer[size];
-
- for ( dotdot = &dotdots[sizeof dotdots]; dotdot != dotdots; )
- {
- dotdot -= 3; /* include one more "/.." section */
- /* (first time is actually "..") */
-
- /* swap stat() info buffers */
- {
- register struct stat *temp = d;
-
- d = dd; /* new current dir is old parent dir */
- dd = temp;
- }
-
- if ( (dirp = opendir( dotdot )) == NULL ) /* new parent */
- goto error; /* errno already set */
-
- if ( fstat( dirp->dd_fd, dd ) != 0 )
- {
- serrno = errno; /* set by fstat() */
- (void)closedir( dirp );
- errno = serrno; /* in case closedir() clobbered it */
- goto error;
- }
-
- if ( d->st_dev == dd->st_dev )
- { /* not crossing a mount point */
- if ( d->st_ino == dd->st_ino )
- { /* root directory */
- dname = "";
- goto append;
- }
-
- do
- if ( (dir = readdir( dirp )) == NULL )
- {
- (void)closedir( dirp );
- errno = ENOENT; /* missing entry */
- goto error;
- }
- while ( dir->d_ino != d->st_ino );
- }
- else { /* crossing a mount point */
- struct stat t; /* info re. test entry */
- char name[sizeof dotdots + 1 + NAME_MAX];
-
- (void)strcpy( name, dotdot );
- dname = &name[strlen( name )];
- *dname++ = '/';
-
- do {
- if ( (dir = readdir( dirp )) == NULL )
- {
- (void)closedir( dirp );
- errno = ENOENT; /* missing entry */
- goto error;
- }
-
- (void)strcpy( dname, dir->d_name );
- /* must fit if NAME_MAX is not a lie */
- }
- while ( stat( name, &t ) != 0
- || t.st_ino != d->st_ino
- || t.st_dev != d->st_dev
- );
- }
-
- dname = dir->d_name;
-
- /* append "/" and reversed dname string onto buffer */
- append:
- if ( endp != buffer /* avoid trailing / in final name */
- || dname[0] == '\0' /* but allow "/" when CWD is root */
- )
- *endp++ = '/';
-
- {
- register char *app; /* traverses dname string */
-
- for ( app = dname; *app != '\0'; ++app )
- ;
-
- if ( app - dname >= bufend - endp )
- {
- (void)closedir( dirp );
- errno = ERANGE; /* won't fit allotted space */
- goto error;
- }
-
- while ( app != dname )
- *endp++ = *--app;
- }
-
- (void)closedir( dirp );
-
- if ( dname[0] == '\0' ) /* reached root; wrap it up */
- {
- register char *startp; /* -> buffer[.] */
-
- *endp = '\0'; /* plant null terminator */
-
- /* straighten out reversed pathname string */
- for ( startp = buffer; --endp > startp; ++startp )
- {
- char temp = *endp;
-
- *endp = *startp;
- *startp = temp;
- }
-
- errno = serrno; /* restore entry errno */
- /* XXX -- if buf==NULL, realloc here? */
- return buffer;
- }
- }
-
- errno = ENOMEM; /* actually, algorithm failure */
-
- error:
- if ( buf == NULL )
- free( (pointer)buffer );
-
- return NULL;
- }
-