Fix the "#ifndef HAVE_SYS_WAIT_H" code path in Program.inc to compile
[oota-llvm.git] / lib / Support / Unix / Path.inc
index 84f8d37493126bb2b9c53677a8a391cf4e36622f..d52604246169a591f999cb120d794fa8cce187d4 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "Unix.h"
 #include "llvm/Support/Process.h"
+#include <limits.h>
+#include <stdio.h>
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 #  include <ndir.h>
 # endif
 #endif
-#if HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#if HAVE_LIMITS_H
-#include <limits.h>
-#endif
 
 #ifdef __APPLE__
 #include <mach-o/dyld.h>
@@ -186,17 +182,17 @@ namespace sys  {
 namespace fs {
 #if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
     defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
-    defined(__linux__) || defined(__CYGWIN__)
+    defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__)
 static int
-test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
-    const char *dir, const char *bin)
-{
+test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
+{  
   struct stat sb;
+  char fullpath[PATH_MAX];
 
-  snprintf(buf, PATH_MAX, "%s/%s", dir, bin);
-  if (realpath(buf, ret) == NULL)
+  snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin);
+  if (realpath(fullpath, ret) == NULL)
     return (1);
-  if (stat(buf, &sb) != 0)
+  if (stat(fullpath, &sb) != 0)
     return (1);
 
   return (0);
@@ -205,20 +201,21 @@ test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
 static char *
 getprogpath(char ret[PATH_MAX], const char *bin)
 {
-  char *pv, *s, *t, buf[PATH_MAX];
+  char *pv, *s, *t;
 
   /* First approach: absolute path. */
   if (bin[0] == '/') {
-    if (test_dir(buf, ret, "/", bin) == 0)
+    if (test_dir(ret, "/", bin) == 0)
       return (ret);
     return (NULL);
   }
 
   /* Second approach: relative path. */
   if (strchr(bin, '/') != NULL) {
-    if (getcwd(buf, PATH_MAX) == NULL)
+    char cwd[PATH_MAX];
+    if (getcwd(cwd, PATH_MAX) == NULL)
       return (NULL);
-    if (test_dir(buf, ret, buf, bin) == 0)
+    if (test_dir(ret, cwd, bin) == 0)
       return (ret);
     return (NULL);
   }
@@ -230,7 +227,7 @@ getprogpath(char ret[PATH_MAX], const char *bin)
   if (pv == NULL)
     return (NULL);
   while ((t = strsep(&s, ":")) != NULL) {
-    if (test_dir(buf, ret, t, bin) == 0) {
+    if (test_dir(ret, t, bin) == 0) {
       free(pv);
       return (ret);
     }
@@ -255,7 +252,8 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
       return link_path;
   }
 #elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
-      defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__)
+      defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
+      defined(__FreeBSD_kernel__)
   char exe_path[PATH_MAX];
 
   if (getprogpath(exe_path, argv0) != NULL)
@@ -297,7 +295,23 @@ TimeValue file_status::getLastModificationTime() const {
   return Ret;
 }
 
+UniqueID file_status::getUniqueID() const {
+  return UniqueID(fs_st_dev, fs_st_ino);
+}
+
 error_code current_path(SmallVectorImpl<char> &result) {
+  result.clear();
+
+  const char *pwd = ::getenv("PWD");
+  llvm::sys::fs::file_status PWDStatus, DotStatus;
+  if (pwd && llvm::sys::path::is_absolute(pwd) &&
+      !llvm::sys::fs::status(pwd, PWDStatus) &&
+      !llvm::sys::fs::status(".", DotStatus) &&
+      PWDStatus.getUniqueID() == DotStatus.getUniqueID()) {
+    result.append(pwd, pwd + strlen(pwd));
+    return error_code::success();
+  }
+
 #ifdef MAXPATHLEN
   result.reserve(MAXPATHLEN);
 #else
@@ -320,65 +334,6 @@ error_code current_path(SmallVectorImpl<char> &result) {
   return error_code::success();
 }
 
-error_code copy_file(const Twine &from, const Twine &to, copy_option copt) {
- // Get arguments.
-  SmallString<128> from_storage;
-  SmallString<128> to_storage;
-  StringRef f = from.toNullTerminatedStringRef(from_storage);
-  StringRef t = to.toNullTerminatedStringRef(to_storage);
-
-  const size_t buf_sz = 32768;
-  char buffer[buf_sz];
-  int from_file = -1, to_file = -1;
-
-  // Open from.
-  if ((from_file = ::open(f.begin(), O_RDONLY)) < 0)
-    return error_code(errno, system_category());
-  AutoFD from_fd(from_file);
-
-  // Stat from.
-  struct stat from_stat;
-  if (::stat(f.begin(), &from_stat) != 0)
-    return error_code(errno, system_category());
-
-  // Setup to flags.
-  int to_flags = O_CREAT | O_WRONLY;
-  if (copt == copy_option::fail_if_exists)
-    to_flags |= O_EXCL;
-
-  // Open to.
-  if ((to_file = ::open(t.begin(), to_flags, from_stat.st_mode)) < 0)
-    return error_code(errno, system_category());
-  AutoFD to_fd(to_file);
-
-  // Copy!
-  ssize_t sz, sz_read = 1, sz_write;
-  while (sz_read > 0 &&
-         (sz_read = ::read(from_fd, buffer, buf_sz)) > 0) {
-    // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
-    // Marc Rochkind, Addison-Wesley, 2004, page 94
-    sz_write = 0;
-    do {
-      if ((sz = ::write(to_fd, buffer + sz_write, sz_read - sz_write)) < 0) {
-        sz_read = sz;  // cause read loop termination.
-        break;         // error.
-      }
-      sz_write += sz;
-    } while (sz_write < sz_read);
-  }
-
-  // After all the file operations above the return value of close actually
-  // matters.
-  if (::close(from_fd.take()) < 0) sz_read = -1;
-  if (::close(to_fd.take()) < 0) sz_read = -1;
-
-  // Check for errors.
-  if (sz_read < 0)
-    return error_code(errno, system_category());
-
-  return error_code::success();
-}
-
 error_code create_directory(const Twine &path, bool &existed) {
   SmallString<128> path_storage;
   StringRef p = path.toNullTerminatedStringRef(path_storage);
@@ -520,18 +475,6 @@ error_code equivalent(const Twine &A, const Twine &B, bool &result) {
   return error_code::success();
 }
 
-error_code getUniqueID(const Twine Path, uint64_t &Result) {
-  SmallString<128> Storage;
-  StringRef P = Path.toNullTerminatedStringRef(Storage);
-
-  struct stat Status;
-  if (::stat(P.begin(), &Status) != 0)
-    return error_code(errno, system_category());
-
-  Result = Status.st_ino;
-  return error_code::success();
-}
-
 static error_code fillStatus(int StatRet, const struct stat &Status,
                              file_status &Result) {
   if (StatRet != 0) {
@@ -588,17 +531,20 @@ error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
   Times[0].tv_nsec = 0;
   Times[1] = Times[0];
   if (::futimens(FD, Times))
+    return error_code(errno, system_category());
+  return error_code::success();
 #elif defined(HAVE_FUTIMES)
   timeval Times[2];
   Times[0].tv_sec = Time.toPosixTime();
   Times[0].tv_usec = 0;
   Times[1] = Times[0];
   if (::futimes(FD, Times))
-#else
-#error Missing futimes() and futimens()
-#endif
     return error_code(errno, system_category());
   return error_code::success();
+#else
+#warning Missing futimes() and futimens()
+  return make_error_code(errc::not_supported);
+#endif
 }
 
 error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
@@ -703,7 +649,7 @@ uint64_t mapped_file_region::size() const {
 
 char *mapped_file_region::data() const {
   assert(Mapping && "Mapping failed but used anyway!");
-  assert(Mode != readonly && "Cannot get non const data for readonly mapping!");
+  assert(Mode != readonly && "Cannot get non-const data for readonly mapping!");
   return reinterpret_cast<char*>(Mapping);
 }
 
@@ -825,6 +771,31 @@ error_code openFileForRead(const Twine &Name, int &ResultFD) {
   return error_code::success();
 }
 
+error_code openFileForWrite(const Twine &Name, int &ResultFD,
+                            sys::fs::OpenFlags Flags, unsigned Mode) {
+  // Verify that we don't have both "append" and "excl".
+  assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
+         "Cannot specify both 'excl' and 'append' file creation flags!");
+
+  int OpenFlags = O_WRONLY | O_CREAT;
+
+  if (Flags & F_Append)
+    OpenFlags |= O_APPEND;
+  else
+    OpenFlags |= O_TRUNC;
+
+  if (Flags & F_Excl)
+    OpenFlags |= O_EXCL;
+
+  SmallString<128> Storage;
+  StringRef P = Name.toNullTerminatedStringRef(Storage);
+  while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
+    if (errno != EINTR)
+      return error_code(errno, system_category());
+  }
+  return error_code::success();
+}
+
 } // end namespace fs
 } // end namespace sys
 } // end namespace llvm