diff libiberty/getpwd.c @ 0:a06113de4d67

first commit
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 17 Jul 2009 14:47:48 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libiberty/getpwd.c	Fri Jul 17 14:47:48 2009 +0900
@@ -0,0 +1,128 @@
+/* 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__ */