mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			129 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
| /* getpwd.c - get the working directory */
 | |
| 
 | |
| /*
 | |
| 
 | |
| @deftypefn Supplemental char* getpwd (void)
 | |
| 
 | |
| Returns the current working directory.  This implementation caches the
 | |
| result on the assumption that the process will not call @code{chdir}
 | |
| between calls to @code{getpwd}.
 | |
| 
 | |
| @end deftypefn
 | |
| 
 | |
| */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include <sys/types.h>
 | |
| 
 | |
| #include <errno.h>
 | |
| #ifndef errno
 | |
| extern int errno;
 | |
| #endif
 | |
| 
 | |
| #ifdef HAVE_STDLIB_H
 | |
| #include <stdlib.h>
 | |
| #endif
 | |
| #ifdef HAVE_UNISTD_H
 | |
| #include <unistd.h>
 | |
| #endif
 | |
| #ifdef HAVE_SYS_PARAM_H
 | |
| #include <sys/param.h>
 | |
| #endif
 | |
| #if HAVE_SYS_STAT_H
 | |
| #include <sys/stat.h>
 | |
| #endif
 | |
| #if HAVE_LIMITS_H
 | |
| #include <limits.h>
 | |
| #endif
 | |
| 
 | |
| #include "libiberty.h"
 | |
| 
 | |
| /* Virtually every UN*X system now in common use (except for pre-4.3-tahoe
 | |
|    BSD systems) now provides getcwd as called for by POSIX.  Allow for
 | |
|    the few exceptions to the general rule here.  */
 | |
| 
 | |
| #if !defined(HAVE_GETCWD) && defined(HAVE_GETWD)
 | |
| /* Prototype in case the system headers doesn't provide it. */
 | |
| extern char *getwd ();
 | |
| #define getcwd(buf,len) getwd(buf)
 | |
| #endif
 | |
| 
 | |
| #ifdef MAXPATHLEN
 | |
| #define GUESSPATHLEN (MAXPATHLEN + 1)
 | |
| #else
 | |
| #define GUESSPATHLEN 100
 | |
| #endif
 | |
| 
 | |
| #if !(defined (VMS) || (defined(_WIN32) && !defined(__CYGWIN__)))
 | |
| 
 | |
| /* Get the working directory.  Use the PWD environment variable if it's
 | |
|    set correctly, since this is faster and gives more uniform answers
 | |
|    to the user.  Yield the working directory if successful; otherwise,
 | |
|    yield 0 and set errno.  */
 | |
| 
 | |
| char *
 | |
| getpwd (void)
 | |
| {
 | |
|   static char *pwd;
 | |
|   static int failure_errno;
 | |
| 
 | |
|   char *p = pwd;
 | |
|   size_t s;
 | |
|   struct stat dotstat, pwdstat;
 | |
| 
 | |
|   if (!p && !(errno = failure_errno))
 | |
|     {
 | |
|       if (! ((p = getenv ("PWD")) != 0
 | |
| 	     && *p == '/'
 | |
| 	     && stat (p, &pwdstat) == 0
 | |
| 	     && stat (".", &dotstat) == 0
 | |
| 	     && dotstat.st_ino == pwdstat.st_ino
 | |
| 	     && dotstat.st_dev == pwdstat.st_dev))
 | |
| 
 | |
| 	/* The shortcut didn't work.  Try the slow, ``sure'' way.  */
 | |
| 	for (s = GUESSPATHLEN;  !getcwd (p = XNEWVEC (char, s), s);  s *= 2)
 | |
| 	  {
 | |
| 	    int e = errno;
 | |
| 	    free (p);
 | |
| #ifdef ERANGE
 | |
| 	    if (e != ERANGE)
 | |
| #endif
 | |
| 	      {
 | |
| 		errno = failure_errno = e;
 | |
| 		p = 0;
 | |
| 		break;
 | |
| 	      }
 | |
| 	  }
 | |
| 
 | |
|       /* Cache the result.  This assumes that the program does
 | |
| 	 not invoke chdir between calls to getpwd.  */
 | |
|       pwd = p;
 | |
|     }
 | |
|   return p;
 | |
| }
 | |
| 
 | |
| #else	/* VMS || _WIN32 && !__CYGWIN__ */
 | |
| 
 | |
| #ifndef MAXPATHLEN
 | |
| #define MAXPATHLEN 255
 | |
| #endif
 | |
| 
 | |
| char *
 | |
| getpwd (void)
 | |
| {
 | |
|   static char *pwd = 0;
 | |
| 
 | |
|   if (!pwd)
 | |
|     pwd = getcwd (XNEWVEC (char, MAXPATHLEN + 1), MAXPATHLEN + 1
 | |
| #ifdef VMS
 | |
| 		  , 0
 | |
| #endif
 | |
| 		  );
 | |
|   return pwd;
 | |
| }
 | |
| 
 | |
| #endif	/* VMS || _WIN32 && !__CYGWIN__ */
 |