diff options
Diffstat (limited to 'dmake/unix/solaris/getcwd.c')
-rw-r--r-- | dmake/unix/solaris/getcwd.c | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/dmake/unix/solaris/getcwd.c b/dmake/unix/solaris/getcwd.c deleted file mode 100644 index f2359bcc795b..000000000000 --- a/dmake/unix/solaris/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; - } - |