make Program::Execute use posix_spawn on systems that support it,
[oota-llvm.git] / lib / System / Unix / Path.inc
1 //===- llvm/System/Unix/Path.cpp - Unix Path Implementation -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Unix specific portion of the Path class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 //===----------------------------------------------------------------------===//
15 //=== WARNING: Implementation here must contain only generic UNIX code that
16 //===          is guaranteed to work on *all* UNIX variants.
17 //===----------------------------------------------------------------------===//
18
19 #include "Unix.h"
20 #if HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 #if HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26 #ifdef HAVE_SYS_MMAN_H
27 #include <sys/mman.h>
28 #endif
29 #ifdef HAVE_SYS_STAT_H
30 #include <sys/stat.h>
31 #endif
32 #if HAVE_UTIME_H
33 #include <utime.h>
34 #endif
35 #if HAVE_TIME_H
36 #include <time.h>
37 #endif
38 #if HAVE_DIRENT_H
39 # include <dirent.h>
40 # define NAMLEN(dirent) strlen((dirent)->d_name)
41 #else
42 # define dirent direct
43 # define NAMLEN(dirent) (dirent)->d_namlen
44 # if HAVE_SYS_NDIR_H
45 #  include <sys/ndir.h>
46 # endif
47 # if HAVE_SYS_DIR_H
48 #  include <sys/dir.h>
49 # endif
50 # if HAVE_NDIR_H
51 #  include <ndir.h>
52 # endif
53 #endif
54
55 #if HAVE_DLFCN_H
56 #include <dlfcn.h>
57 #endif
58
59 #ifdef __APPLE__
60 #include <mach-o/dyld.h>
61 #endif
62
63 // Put in a hack for Cygwin which falsely reports that the mkdtemp function
64 // is available when it is not.
65 #ifdef __CYGWIN__
66 # undef HAVE_MKDTEMP
67 #endif
68
69 namespace {
70 inline bool lastIsSlash(const std::string& path) {
71   return !path.empty() && path[path.length() - 1] == '/';
72 }
73
74 }
75
76 namespace llvm {
77 using namespace sys;
78
79 const char sys::PathSeparator = ':';
80
81 Path::Path(StringRef p)
82   : path(p) {}
83
84 Path::Path(const char *StrStart, unsigned StrLen)
85   : path(StrStart, StrLen) {}
86
87 Path&
88 Path::operator=(StringRef that) {
89   path.assign(that.data(), that.size());
90   return *this;
91 }
92
93 bool
94 Path::isValid() const {
95   // Check some obvious things
96   if (path.empty())
97     return false;
98   return path.length() < MAXPATHLEN;
99 }
100
101 bool
102 Path::isAbsolute(const char *NameStart, unsigned NameLen) {
103   assert(NameStart);
104   if (NameLen == 0)
105     return false;
106   return NameStart[0] == '/';
107 }
108
109 bool
110 Path::isAbsolute() const {
111   if (path.empty())
112     return false;
113   return path[0] == '/';
114 }
115
116 void Path::makeAbsolute() {
117   if (isAbsolute())
118     return;
119
120   Path CWD = Path::GetCurrentDirectory();
121   assert(CWD.isAbsolute() && "GetCurrentDirectory returned relative path!");
122
123   CWD.appendComponent(path);
124
125   path = CWD.str();
126 }
127
128 Path
129 Path::GetRootDirectory() {
130   Path result;
131   result.set("/");
132   return result;
133 }
134
135 Path
136 Path::GetTemporaryDirectory(std::string *ErrMsg) {
137 #if defined(HAVE_MKDTEMP)
138   // The best way is with mkdtemp but that's not available on many systems,
139   // Linux and FreeBSD have it. Others probably won't.
140   char pathname[MAXPATHLEN];
141   strcpy(pathname,"/tmp/llvm_XXXXXX");
142   if (0 == mkdtemp(pathname)) {
143     MakeErrMsg(ErrMsg,
144       std::string(pathname) + ": can't create temporary directory");
145     return Path();
146   }
147   Path result;
148   result.set(pathname);
149   assert(result.isValid() && "mkdtemp didn't create a valid pathname!");
150   return result;
151 #elif defined(HAVE_MKSTEMP)
152   // If no mkdtemp is available, mkstemp can be used to create a temporary file
153   // which is then removed and created as a directory. We prefer this over
154   // mktemp because of mktemp's inherent security and threading risks. We still
155   // have a slight race condition from the time the temporary file is created to
156   // the time it is re-created as a directoy.
157   char pathname[MAXPATHLEN];
158   strcpy(pathname, "/tmp/llvm_XXXXXX");
159   int fd = 0;
160   if (-1 == (fd = mkstemp(pathname))) {
161     MakeErrMsg(ErrMsg,
162       std::string(pathname) + ": can't create temporary directory");
163     return Path();
164   }
165   ::close(fd);
166   ::unlink(pathname); // start race condition, ignore errors
167   if (-1 == ::mkdir(pathname, S_IRWXU)) { // end race condition
168     MakeErrMsg(ErrMsg,
169       std::string(pathname) + ": can't create temporary directory");
170     return Path();
171   }
172   Path result;
173   result.set(pathname);
174   assert(result.isValid() && "mkstemp didn't create a valid pathname!");
175   return result;
176 #elif defined(HAVE_MKTEMP)
177   // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have
178   // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable
179   // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing
180   // the XXXXXX with the pid of the process and a letter. That leads to only
181   // twenty six temporary files that can be generated.
182   char pathname[MAXPATHLEN];
183   strcpy(pathname, "/tmp/llvm_XXXXXX");
184   char *TmpName = ::mktemp(pathname);
185   if (TmpName == 0) {
186     MakeErrMsg(ErrMsg,
187       std::string(TmpName) + ": can't create unique directory name");
188     return Path();
189   }
190   if (-1 == ::mkdir(TmpName, S_IRWXU)) {
191     MakeErrMsg(ErrMsg,
192         std::string(TmpName) + ": can't create temporary directory");
193     return Path();
194   }
195   Path result;
196   result.set(TmpName);
197   assert(result.isValid() && "mktemp didn't create a valid pathname!");
198   return result;
199 #else
200   // This is the worst case implementation. tempnam(3) leaks memory unless its
201   // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread
202   // issues. The mktemp(3) function doesn't have enough variability in the
203   // temporary name generated. So, we provide our own implementation that
204   // increments an integer from a random number seeded by the current time. This
205   // should be sufficiently unique that we don't have many collisions between
206   // processes. Generally LLVM processes don't run very long and don't use very
207   // many temporary files so this shouldn't be a big issue for LLVM.
208   static time_t num = ::time(0);
209   char pathname[MAXPATHLEN];
210   do {
211     num++;
212     sprintf(pathname, "/tmp/llvm_%010u", unsigned(num));
213   } while ( 0 == access(pathname, F_OK ) );
214   if (-1 == ::mkdir(pathname, S_IRWXU)) {
215     MakeErrMsg(ErrMsg,
216       std::string(pathname) + ": can't create temporary directory");
217     return Path();
218   }
219   Path result;
220   result.set(pathname);
221   assert(result.isValid() && "mkstemp didn't create a valid pathname!");
222   return result;
223 #endif
224 }
225
226 void
227 Path::GetSystemLibraryPaths(std::vector<sys::Path>& Paths) {
228 #ifdef LTDL_SHLIBPATH_VAR
229   char* env_var = getenv(LTDL_SHLIBPATH_VAR);
230   if (env_var != 0) {
231     getPathList(env_var,Paths);
232   }
233 #endif
234   // FIXME: Should this look at LD_LIBRARY_PATH too?
235   Paths.push_back(sys::Path("/usr/local/lib/"));
236   Paths.push_back(sys::Path("/usr/X11R6/lib/"));
237   Paths.push_back(sys::Path("/usr/lib/"));
238   Paths.push_back(sys::Path("/lib/"));
239 }
240
241 void
242 Path::GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths) {
243   char * env_var = getenv("LLVM_LIB_SEARCH_PATH");
244   if (env_var != 0) {
245     getPathList(env_var,Paths);
246   }
247 #ifdef LLVM_LIBDIR
248   {
249     Path tmpPath;
250     if (tmpPath.set(LLVM_LIBDIR))
251       if (tmpPath.canRead())
252         Paths.push_back(tmpPath);
253   }
254 #endif
255   GetSystemLibraryPaths(Paths);
256 }
257
258 Path
259 Path::GetLLVMDefaultConfigDir() {
260   return Path("/etc/llvm/");
261 }
262
263 Path
264 Path::GetUserHomeDirectory() {
265   const char* home = getenv("HOME");
266   if (home) {
267     Path result;
268     if (result.set(home))
269       return result;
270   }
271   return GetRootDirectory();
272 }
273
274 Path
275 Path::GetCurrentDirectory() {
276   char pathname[MAXPATHLEN];
277   if (!getcwd(pathname,MAXPATHLEN)) {
278     assert (false && "Could not query current working directory.");
279     return Path("");
280   }
281
282   return Path(pathname);
283 }
284
285 #ifdef __FreeBSD__
286 static int
287 test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
288     const char *dir, const char *bin)
289 {
290   struct stat sb;
291
292   snprintf(buf, PATH_MAX, "%s//%s", dir, bin);
293   if (realpath(buf, ret) == NULL)
294     return (1);
295   if (stat(buf, &sb) != 0)
296     return (1);
297
298   return (0);
299 }
300
301 static char *
302 getprogpath(char ret[PATH_MAX], const char *bin)
303 {
304   char *pv, *s, *t, buf[PATH_MAX];
305
306   /* First approach: absolute path. */
307   if (bin[0] == '/') {
308     if (test_dir(buf, ret, "/", bin) == 0)
309       return (ret);
310     return (NULL);
311   }
312
313   /* Second approach: relative path. */
314   if (strchr(bin, '/') != NULL) {
315     if (getcwd(buf, PATH_MAX) == NULL)
316       return (NULL);
317     if (test_dir(buf, ret, buf, bin) == 0)
318       return (ret);
319     return (NULL);
320   }
321
322   /* Third approach: $PATH */
323   if ((pv = getenv("PATH")) == NULL)
324     return (NULL);
325   s = pv = strdup(pv);
326   if (pv == NULL)
327     return (NULL);
328   while ((t = strsep(&s, ":")) != NULL) {
329     if (test_dir(buf, ret, t, bin) == 0) {
330       free(pv);
331       return (ret);
332     }
333   }
334   free(pv);
335   return (NULL);
336 }
337 #endif // __FreeBSD__
338
339 /// GetMainExecutable - Return the path to the main executable, given the
340 /// value of argv[0] from program startup.
341 Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
342 #if defined(__APPLE__)
343   // On OS X the executable path is saved to the stack by dyld. Reading it
344   // from there is much faster than calling dladdr, especially for large
345   // binaries with symbols.
346   char exe_path[MAXPATHLEN];
347   uint32_t size = sizeof(exe_path);
348   if (_NSGetExecutablePath(exe_path, &size) == 0) {
349     char link_path[MAXPATHLEN];
350     if (realpath(exe_path, link_path))
351       return Path(std::string(link_path));
352   }
353 #elif defined(__FreeBSD__)
354   char exe_path[PATH_MAX];
355
356   if (getprogpath(exe_path, argv0) != NULL)
357     return Path(std::string(exe_path));
358 #elif defined(__linux__) || defined(__CYGWIN__)
359   char exe_path[MAXPATHLEN];
360   ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
361   if (len >= 0)
362     return Path(std::string(exe_path, len));
363 #elif defined(HAVE_DLFCN_H)
364   // Use dladdr to get executable path if available.
365   Dl_info DLInfo;
366   int err = dladdr(MainAddr, &DLInfo);
367   if (err == 0)
368     return Path();
369
370   // If the filename is a symlink, we need to resolve and return the location of
371   // the actual executable.
372   char link_path[MAXPATHLEN];
373   if (realpath(DLInfo.dli_fname, link_path))
374     return Path(std::string(link_path));
375 #endif
376   return Path();
377 }
378
379
380 StringRef Path::getDirname() const {
381   return getDirnameCharSep(path, "/");
382 }
383
384 StringRef
385 Path::getBasename() const {
386   // Find the last slash
387   std::string::size_type slash = path.rfind('/');
388   if (slash == std::string::npos)
389     slash = 0;
390   else
391     slash++;
392
393   std::string::size_type dot = path.rfind('.');
394   if (dot == std::string::npos || dot < slash)
395     return StringRef(path).substr(slash);
396   else
397     return StringRef(path).substr(slash, dot - slash);
398 }
399
400 StringRef
401 Path::getSuffix() const {
402   // Find the last slash
403   std::string::size_type slash = path.rfind('/');
404   if (slash == std::string::npos)
405     slash = 0;
406   else
407     slash++;
408
409   std::string::size_type dot = path.rfind('.');
410   if (dot == std::string::npos || dot < slash)
411     return StringRef("");
412   else
413     return StringRef(path).substr(dot + 1);
414 }
415
416 bool Path::getMagicNumber(std::string &Magic, unsigned len) const {
417   assert(len < 1024 && "Request for magic string too long");
418   char Buf[1025];
419   int fd = ::open(path.c_str(), O_RDONLY);
420   if (fd < 0)
421     return false;
422   ssize_t bytes_read = ::read(fd, Buf, len);
423   ::close(fd);
424   if (ssize_t(len) != bytes_read) {
425     Magic.clear();
426     return false;
427   }
428   Magic.assign(Buf, len);
429   return true;
430 }
431
432 bool
433 Path::exists() const {
434   return 0 == access(path.c_str(), F_OK );
435 }
436
437 bool
438 Path::isDirectory() const {
439   struct stat buf;
440   if (0 != stat(path.c_str(), &buf))
441     return false;
442   return buf.st_mode & S_IFDIR ? true : false;
443 }
444
445 bool
446 Path::canRead() const {
447   return 0 == access(path.c_str(), R_OK);
448 }
449
450 bool
451 Path::canWrite() const {
452   return 0 == access(path.c_str(), W_OK);
453 }
454
455 bool
456 Path::isRegularFile() const {
457   // Get the status so we can determine if it's a file or directory
458   struct stat buf;
459
460   if (0 != stat(path.c_str(), &buf))
461     return false;
462
463   if (S_ISREG(buf.st_mode))
464     return true;
465
466   return false;
467 }
468
469 bool
470 Path::canExecute() const {
471   if (0 != access(path.c_str(), R_OK | X_OK ))
472     return false;
473   struct stat buf;
474   if (0 != stat(path.c_str(), &buf))
475     return false;
476   if (!S_ISREG(buf.st_mode))
477     return false;
478   return true;
479 }
480
481 StringRef
482 Path::getLast() const {
483   // Find the last slash
484   size_t pos = path.rfind('/');
485
486   // Handle the corner cases
487   if (pos == std::string::npos)
488     return path;
489
490   // If the last character is a slash
491   if (pos == path.length()-1) {
492     // Find the second to last slash
493     size_t pos2 = path.rfind('/', pos-1);
494     if (pos2 == std::string::npos)
495       return StringRef(path).substr(0,pos);
496     else
497       return StringRef(path).substr(pos2+1,pos-pos2-1);
498   }
499   // Return everything after the last slash
500   return StringRef(path).substr(pos+1);
501 }
502
503 const FileStatus *
504 PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const {
505   if (!fsIsValid || update) {
506     struct stat buf;
507     if (0 != stat(path.c_str(), &buf)) {
508       MakeErrMsg(ErrStr, path + ": can't get status of file");
509       return 0;
510     }
511     status.fileSize = buf.st_size;
512     status.modTime.fromEpochTime(buf.st_mtime);
513     status.mode = buf.st_mode;
514     status.user = buf.st_uid;
515     status.group = buf.st_gid;
516     status.uniqueID = uint64_t(buf.st_ino);
517     status.isDir  = S_ISDIR(buf.st_mode);
518     status.isFile = S_ISREG(buf.st_mode);
519     fsIsValid = true;
520   }
521   return &status;
522 }
523
524 static bool AddPermissionBits(const Path &File, int bits) {
525   // Get the umask value from the operating system.  We want to use it
526   // when changing the file's permissions. Since calling umask() sets
527   // the umask and returns its old value, we must call it a second
528   // time to reset it to the user's preference.
529   int mask = umask(0777); // The arg. to umask is arbitrary.
530   umask(mask);            // Restore the umask.
531
532   // Get the file's current mode.
533   struct stat buf;
534   if (0 != stat(File.c_str(), &buf))
535     return false;
536   // Change the file to have whichever permissions bits from 'bits'
537   // that the umask would not disable.
538   if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1)
539       return false;
540   return true;
541 }
542
543 bool Path::makeReadableOnDisk(std::string* ErrMsg) {
544   if (!AddPermissionBits(*this, 0444))
545     return MakeErrMsg(ErrMsg, path + ": can't make file readable");
546   return false;
547 }
548
549 bool Path::makeWriteableOnDisk(std::string* ErrMsg) {
550   if (!AddPermissionBits(*this, 0222))
551     return MakeErrMsg(ErrMsg, path + ": can't make file writable");
552   return false;
553 }
554
555 bool Path::makeExecutableOnDisk(std::string* ErrMsg) {
556   if (!AddPermissionBits(*this, 0111))
557     return MakeErrMsg(ErrMsg, path + ": can't make file executable");
558   return false;
559 }
560
561 bool
562 Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const {
563   DIR* direntries = ::opendir(path.c_str());
564   if (direntries == 0)
565     return MakeErrMsg(ErrMsg, path + ": can't open directory");
566
567   std::string dirPath = path;
568   if (!lastIsSlash(dirPath))
569     dirPath += '/';
570
571   result.clear();
572   struct dirent* de = ::readdir(direntries);
573   for ( ; de != 0; de = ::readdir(direntries)) {
574     if (de->d_name[0] != '.') {
575       Path aPath(dirPath + (const char*)de->d_name);
576       struct stat st;
577       if (0 != lstat(aPath.path.c_str(), &st)) {
578         if (S_ISLNK(st.st_mode))
579           continue; // dangling symlink -- ignore
580         return MakeErrMsg(ErrMsg,
581                           aPath.path +  ": can't determine file object type");
582       }
583       result.insert(aPath);
584     }
585   }
586
587   closedir(direntries);
588   return false;
589 }
590
591 bool
592 Path::set(StringRef a_path) {
593   if (a_path.empty())
594     return false;
595   std::string save(path);
596   path = a_path;
597   if (!isValid()) {
598     path = save;
599     return false;
600   }
601   return true;
602 }
603
604 bool
605 Path::appendComponent(StringRef name) {
606   if (name.empty())
607     return false;
608   std::string save(path);
609   if (!lastIsSlash(path))
610     path += '/';
611   path += name;
612   if (!isValid()) {
613     path = save;
614     return false;
615   }
616   return true;
617 }
618
619 bool
620 Path::eraseComponent() {
621   size_t slashpos = path.rfind('/',path.size());
622   if (slashpos == 0 || slashpos == std::string::npos) {
623     path.erase();
624     return true;
625   }
626   if (slashpos == path.size() - 1)
627     slashpos = path.rfind('/',slashpos-1);
628   if (slashpos == std::string::npos) {
629     path.erase();
630     return true;
631   }
632   path.erase(slashpos);
633   return true;
634 }
635
636 bool
637 Path::appendSuffix(StringRef suffix) {
638   std::string save(path);
639   path.append(".");
640   path.append(suffix);
641   if (!isValid()) {
642     path = save;
643     return false;
644   }
645   return true;
646 }
647
648 bool
649 Path::eraseSuffix() {
650   std::string save = path;
651   size_t dotpos = path.rfind('.',path.size());
652   size_t slashpos = path.rfind('/',path.size());
653   if (dotpos != std::string::npos) {
654     if (slashpos == std::string::npos || dotpos > slashpos+1) {
655       path.erase(dotpos, path.size()-dotpos);
656       return true;
657     }
658   }
659   if (!isValid())
660     path = save;
661   return false;
662 }
663
664 static bool createDirectoryHelper(char* beg, char* end, bool create_parents) {
665
666   if (access(beg, R_OK | W_OK) == 0)
667     return false;
668
669   if (create_parents) {
670
671     char* c = end;
672
673     for (; c != beg; --c)
674       if (*c == '/') {
675
676         // Recurse to handling the parent directory.
677         *c = '\0';
678         bool x = createDirectoryHelper(beg, c, create_parents);
679         *c = '/';
680
681         // Return if we encountered an error.
682         if (x)
683           return true;
684
685         break;
686       }
687   }
688
689   return mkdir(beg, S_IRWXU | S_IRWXG) != 0;
690 }
691
692 bool
693 Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) {
694   // Get a writeable copy of the path name
695   char pathname[MAXPATHLEN];
696   path.copy(pathname,MAXPATHLEN);
697
698   // Null-terminate the last component
699   size_t lastchar = path.length() - 1 ;
700
701   if (pathname[lastchar] != '/')
702     ++lastchar;
703
704   pathname[lastchar] = 0;
705
706   if (createDirectoryHelper(pathname, pathname+lastchar, create_parents))
707     return MakeErrMsg(ErrMsg,
708                       std::string(pathname) + ": can't create directory");
709
710   return false;
711 }
712
713 bool
714 Path::createFileOnDisk(std::string* ErrMsg) {
715   // Create the file
716   int fd = ::creat(path.c_str(), S_IRUSR | S_IWUSR);
717   if (fd < 0)
718     return MakeErrMsg(ErrMsg, path + ": can't create file");
719   ::close(fd);
720   return false;
721 }
722
723 bool
724 Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
725   // Make this into a unique file name
726   if (makeUnique( reuse_current, ErrMsg ))
727     return true;
728
729   // create the file
730   int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666);
731   if (fd < 0)
732     return MakeErrMsg(ErrMsg, path + ": can't create temporary file");
733   ::close(fd);
734   return false;
735 }
736
737 bool
738 Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
739   // Get the status so we can determine if it's a file or directory.
740   struct stat buf;
741   if (0 != stat(path.c_str(), &buf)) {
742     MakeErrMsg(ErrStr, path + ": can't get status of file");
743     return true;
744   }
745
746   // Note: this check catches strange situations. In all cases, LLVM should
747   // only be involved in the creation and deletion of regular files.  This
748   // check ensures that what we're trying to erase is a regular file. It
749   // effectively prevents LLVM from erasing things like /dev/null, any block
750   // special file, or other things that aren't "regular" files.
751   if (S_ISREG(buf.st_mode)) {
752     if (unlink(path.c_str()) != 0)
753       return MakeErrMsg(ErrStr, path + ": can't destroy file");
754     return false;
755   }
756
757   if (!S_ISDIR(buf.st_mode)) {
758     if (ErrStr) *ErrStr = "not a file or directory";
759     return true;
760   }
761
762   if (remove_contents) {
763     // Recursively descend the directory to remove its contents.
764     std::string cmd = "/bin/rm -rf " + path;
765     if (system(cmd.c_str()) != 0) {
766       MakeErrMsg(ErrStr, path + ": failed to recursively remove directory.");
767       return true;
768     }
769     return false;
770   }
771
772   // Otherwise, try to just remove the one directory.
773   char pathname[MAXPATHLEN];
774   path.copy(pathname, MAXPATHLEN);
775   size_t lastchar = path.length() - 1;
776   if (pathname[lastchar] == '/')
777     pathname[lastchar] = 0;
778   else
779     pathname[lastchar+1] = 0;
780
781   if (rmdir(pathname) != 0)
782     return MakeErrMsg(ErrStr,
783       std::string(pathname) + ": can't erase directory");
784   return false;
785 }
786
787 bool
788 Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) {
789   if (0 != ::rename(path.c_str(), newName.c_str()))
790     return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" +
791                newName.str() + "'");
792   return false;
793 }
794
795 bool
796 Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
797   struct utimbuf utb;
798   utb.actime = si.modTime.toPosixTime();
799   utb.modtime = utb.actime;
800   if (0 != ::utime(path.c_str(),&utb))
801     return MakeErrMsg(ErrStr, path + ": can't set file modification time");
802   if (0 != ::chmod(path.c_str(),si.mode))
803     return MakeErrMsg(ErrStr, path + ": can't set mode");
804   return false;
805 }
806
807 bool
808 sys::CopyFile(const sys::Path &Dest, const sys::Path &Src, std::string* ErrMsg){
809   int inFile = -1;
810   int outFile = -1;
811   inFile = ::open(Src.c_str(), O_RDONLY);
812   if (inFile == -1)
813     return MakeErrMsg(ErrMsg, Src.str() +
814       ": can't open source file to copy");
815
816   outFile = ::open(Dest.c_str(), O_WRONLY|O_CREAT, 0666);
817   if (outFile == -1) {
818     ::close(inFile);
819     return MakeErrMsg(ErrMsg, Dest.str() +
820       ": can't create destination file for copy");
821   }
822
823   char Buffer[16*1024];
824   while (ssize_t Amt = ::read(inFile, Buffer, 16*1024)) {
825     if (Amt == -1) {
826       if (errno != EINTR && errno != EAGAIN) {
827         ::close(inFile);
828         ::close(outFile);
829         return MakeErrMsg(ErrMsg, Src.str()+": can't read source file");
830       }
831     } else {
832       char *BufPtr = Buffer;
833       while (Amt) {
834         ssize_t AmtWritten = ::write(outFile, BufPtr, Amt);
835         if (AmtWritten == -1) {
836           if (errno != EINTR && errno != EAGAIN) {
837             ::close(inFile);
838             ::close(outFile);
839             return MakeErrMsg(ErrMsg, Dest.str() +
840               ": can't write destination file");
841           }
842         } else {
843           Amt -= AmtWritten;
844           BufPtr += AmtWritten;
845         }
846       }
847     }
848   }
849   ::close(inFile);
850   ::close(outFile);
851   return false;
852 }
853
854 bool
855 Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
856   if (reuse_current && !exists())
857     return false; // File doesn't exist already, just use it!
858
859   // Append an XXXXXX pattern to the end of the file for use with mkstemp,
860   // mktemp or our own implementation.
861   std::string Buf(path);
862   if (isDirectory())
863     Buf += "/XXXXXX";
864   else
865     Buf += "-XXXXXX";
866
867 #if defined(HAVE_MKSTEMP)
868   int TempFD;
869   if ((TempFD = mkstemp((char*)Buf.c_str())) == -1)
870     return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
871
872   // We don't need to hold the temp file descriptor... we will trust that no one
873   // will overwrite/delete the file before we can open it again.
874   close(TempFD);
875
876   // Save the name
877   path = Buf;
878 #elif defined(HAVE_MKTEMP)
879   // If we don't have mkstemp, use the old and obsolete mktemp function.
880   if (mktemp(Buf.c_str()) == 0)
881     return MakeErrMsg(ErrMsg, path + ": can't make unique filename");
882
883   // Save the name
884   path = Buf;
885 #else
886   // Okay, looks like we have to do it all by our lonesome.
887   static unsigned FCounter = 0;
888   unsigned offset = path.size() + 1;
889   while (FCounter < 999999 && exists()) {
890     sprintf(Buf.data()+offset, "%06u", ++FCounter);
891     path = Buf;
892   }
893   if (FCounter > 999999)
894     return MakeErrMsg(ErrMsg,
895       path + ": can't make unique filename: too many files");
896 #endif
897   return false;
898 }
899
900 const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
901   int Flags = MAP_PRIVATE;
902 #ifdef MAP_FILE
903   Flags |= MAP_FILE;
904 #endif
905   void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0);
906   if (BasePtr == MAP_FAILED)
907     return 0;
908   return (const char*)BasePtr;
909 }
910
911 void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) {
912   ::munmap((void*)BasePtr, FileSize);
913 }
914
915 } // end llvm namespace