1//===-- Path.cpp - Implement OS Path Concept ------------------------------===//
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 operating system Path API.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/Errc.h"
15#include "llvm/Support/Path.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/ErrorHandling.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Process.h"
20#include <cctype>
21#include <cstdio>
22#include <cstring>
23#include <fcntl.h>
24
25#if !defined(_MSC_VER) && !defined(__MINGW32__)
26#include <unistd.h>
27#else
28#include <io.h>
29#endif
30
31using namespace llvm;
32
33namespace {
34  using llvm::StringRef;
35  using llvm::sys::path::is_separator;
36
37#ifdef LLVM_ON_WIN32
38  const char *separators = "\\/";
39  const char preferred_separator = '\\';
40#else
41  const char  separators = '/';
42  const char preferred_separator = '/';
43#endif
44
45  StringRef find_first_component(StringRef path) {
46    // Look for this first component in the following order.
47    // * empty (in this case we return an empty string)
48    // * either C: or {//,\\}net.
49    // * {/,\}
50    // * {.,..}
51    // * {file,directory}name
52
53    if (path.empty())
54      return path;
55
56#ifdef LLVM_ON_WIN32
57    // C:
58    if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
59        path[1] == ':')
60      return path.substr(0, 2);
61#endif
62
63    // //net
64    if ((path.size() > 2) &&
65        is_separator(path[0]) &&
66        path[0] == path[1] &&
67        !is_separator(path[2])) {
68      // Find the next directory separator.
69      size_t end = path.find_first_of(separators, 2);
70      return path.substr(0, end);
71    }
72
73    // {/,\}
74    if (is_separator(path[0]))
75      return path.substr(0, 1);
76
77    if (path.startswith(".."))
78      return path.substr(0, 2);
79
80    if (path[0] == '.')
81      return path.substr(0, 1);
82
83    // * {file,directory}name
84    size_t end = path.find_first_of(separators);
85    return path.substr(0, end);
86  }
87
88  size_t filename_pos(StringRef str) {
89    if (str.size() == 2 &&
90        is_separator(str[0]) &&
91        str[0] == str[1])
92      return 0;
93
94    if (str.size() > 0 && is_separator(str[str.size() - 1]))
95      return str.size() - 1;
96
97    size_t pos = str.find_last_of(separators, str.size() - 1);
98
99#ifdef LLVM_ON_WIN32
100    if (pos == StringRef::npos)
101      pos = str.find_last_of(':', str.size() - 2);
102#endif
103
104    if (pos == StringRef::npos ||
105        (pos == 1 && is_separator(str[0])))
106      return 0;
107
108    return pos + 1;
109  }
110
111  size_t root_dir_start(StringRef str) {
112    // case "c:/"
113#ifdef LLVM_ON_WIN32
114    if (str.size() > 2 &&
115        str[1] == ':' &&
116        is_separator(str[2]))
117      return 2;
118#endif
119
120    // case "//"
121    if (str.size() == 2 &&
122        is_separator(str[0]) &&
123        str[0] == str[1])
124      return StringRef::npos;
125
126    // case "//net"
127    if (str.size() > 3 &&
128        is_separator(str[0]) &&
129        str[0] == str[1] &&
130        !is_separator(str[2])) {
131      return str.find_first_of(separators, 2);
132    }
133
134    // case "/"
135    if (str.size() > 0 && is_separator(str[0]))
136      return 0;
137
138    return StringRef::npos;
139  }
140
141  size_t parent_path_end(StringRef path) {
142    size_t end_pos = filename_pos(path);
143
144    bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
145
146    // Skip separators except for root dir.
147    size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
148
149    while(end_pos > 0 &&
150          (end_pos - 1) != root_dir_pos &&
151          is_separator(path[end_pos - 1]))
152      --end_pos;
153
154    if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
155      return StringRef::npos;
156
157    return end_pos;
158  }
159} // end unnamed namespace
160
161enum FSEntity {
162  FS_Dir,
163  FS_File,
164  FS_Name
165};
166
167// Implemented in Unix/Path.inc and Windows/Path.inc.
168static std::error_code TempDir(SmallVectorImpl<char> &result);
169
170static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
171                                          SmallVectorImpl<char> &ResultPath,
172                                          bool MakeAbsolute, unsigned Mode,
173                                          FSEntity Type) {
174  SmallString<128> ModelStorage;
175  Model.toVector(ModelStorage);
176
177  if (MakeAbsolute) {
178    // Make model absolute by prepending a temp directory if it's not already.
179    if (!sys::path::is_absolute(Twine(ModelStorage))) {
180      SmallString<128> TDir;
181      if (std::error_code EC = TempDir(TDir))
182        return EC;
183      sys::path::append(TDir, Twine(ModelStorage));
184      ModelStorage.swap(TDir);
185    }
186  }
187
188  // From here on, DO NOT modify model. It may be needed if the randomly chosen
189  // path already exists.
190  ResultPath = ModelStorage;
191  // Null terminate.
192  ResultPath.push_back(0);
193  ResultPath.pop_back();
194
195retry_random_path:
196  // Replace '%' with random chars.
197  for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
198    if (ModelStorage[i] == '%')
199      ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
200  }
201
202  // Try to open + create the file.
203  switch (Type) {
204  case FS_File: {
205    if (std::error_code EC =
206            sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
207                                      sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
208      if (EC == errc::file_exists)
209        goto retry_random_path;
210      return EC;
211    }
212
213    return std::error_code();
214  }
215
216  case FS_Name: {
217    bool Exists;
218    std::error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
219    if (EC)
220      return EC;
221    if (Exists)
222      goto retry_random_path;
223    return std::error_code();
224  }
225
226  case FS_Dir: {
227    if (std::error_code EC =
228            sys::fs::create_directory(ResultPath.begin(), false)) {
229      if (EC == errc::file_exists)
230        goto retry_random_path;
231      return EC;
232    }
233    return std::error_code();
234  }
235  }
236  llvm_unreachable("Invalid Type");
237}
238
239namespace llvm {
240namespace sys  {
241namespace path {
242
243const_iterator begin(StringRef path) {
244  const_iterator i;
245  i.Path      = path;
246  i.Component = find_first_component(path);
247  i.Position  = 0;
248  return i;
249}
250
251const_iterator end(StringRef path) {
252  const_iterator i;
253  i.Path      = path;
254  i.Position  = path.size();
255  return i;
256}
257
258const_iterator &const_iterator::operator++() {
259  assert(Position < Path.size() && "Tried to increment past end!");
260
261  // Increment Position to past the current component
262  Position += Component.size();
263
264  // Check for end.
265  if (Position == Path.size()) {
266    Component = StringRef();
267    return *this;
268  }
269
270  // Both POSIX and Windows treat paths that begin with exactly two separators
271  // specially.
272  bool was_net = Component.size() > 2 &&
273    is_separator(Component[0]) &&
274    Component[1] == Component[0] &&
275    !is_separator(Component[2]);
276
277  // Handle separators.
278  if (is_separator(Path[Position])) {
279    // Root dir.
280    if (was_net
281#ifdef LLVM_ON_WIN32
282        // c:/
283        || Component.endswith(":")
284#endif
285        ) {
286      Component = Path.substr(Position, 1);
287      return *this;
288    }
289
290    // Skip extra separators.
291    while (Position != Path.size() &&
292           is_separator(Path[Position])) {
293      ++Position;
294    }
295
296    // Treat trailing '/' as a '.'.
297    if (Position == Path.size()) {
298      --Position;
299      Component = ".";
300      return *this;
301    }
302  }
303
304  // Find next component.
305  size_t end_pos = Path.find_first_of(separators, Position);
306  Component = Path.slice(Position, end_pos);
307
308  return *this;
309}
310
311const_iterator &const_iterator::operator--() {
312  // If we're at the end and the previous char was a '/', return '.' unless
313  // we are the root path.
314  size_t root_dir_pos = root_dir_start(Path);
315  if (Position == Path.size() &&
316      Path.size() > root_dir_pos + 1 &&
317      is_separator(Path[Position - 1])) {
318    --Position;
319    Component = ".";
320    return *this;
321  }
322
323  // Skip separators unless it's the root directory.
324  size_t end_pos = Position;
325
326  while(end_pos > 0 &&
327        (end_pos - 1) != root_dir_pos &&
328        is_separator(Path[end_pos - 1]))
329    --end_pos;
330
331  // Find next separator.
332  size_t start_pos = filename_pos(Path.substr(0, end_pos));
333  Component = Path.slice(start_pos, end_pos);
334  Position = start_pos;
335  return *this;
336}
337
338bool const_iterator::operator==(const const_iterator &RHS) const {
339  return Path.begin() == RHS.Path.begin() &&
340         Position == RHS.Position;
341}
342
343bool const_iterator::operator!=(const const_iterator &RHS) const {
344  return !(*this == RHS);
345}
346
347ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
348  return Position - RHS.Position;
349}
350
351const StringRef root_path(StringRef path) {
352  const_iterator b = begin(path),
353                 pos = b,
354                 e = end(path);
355  if (b != e) {
356    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
357    bool has_drive =
358#ifdef LLVM_ON_WIN32
359      b->endswith(":");
360#else
361      false;
362#endif
363
364    if (has_net || has_drive) {
365      if ((++pos != e) && is_separator((*pos)[0])) {
366        // {C:/,//net/}, so get the first two components.
367        return path.substr(0, b->size() + pos->size());
368      } else {
369        // just {C:,//net}, return the first component.
370        return *b;
371      }
372    }
373
374    // POSIX style root directory.
375    if (is_separator((*b)[0])) {
376      return *b;
377    }
378  }
379
380  return StringRef();
381}
382
383const StringRef root_name(StringRef path) {
384  const_iterator b = begin(path),
385                 e = end(path);
386  if (b != e) {
387    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
388    bool has_drive =
389#ifdef LLVM_ON_WIN32
390      b->endswith(":");
391#else
392      false;
393#endif
394
395    if (has_net || has_drive) {
396      // just {C:,//net}, return the first component.
397      return *b;
398    }
399  }
400
401  // No path or no name.
402  return StringRef();
403}
404
405const StringRef root_directory(StringRef path) {
406  const_iterator b = begin(path),
407                 pos = b,
408                 e = end(path);
409  if (b != e) {
410    bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
411    bool has_drive =
412#ifdef LLVM_ON_WIN32
413      b->endswith(":");
414#else
415      false;
416#endif
417
418    if ((has_net || has_drive) &&
419        // {C:,//net}, skip to the next component.
420        (++pos != e) && is_separator((*pos)[0])) {
421      return *pos;
422    }
423
424    // POSIX style root directory.
425    if (!has_net && is_separator((*b)[0])) {
426      return *b;
427    }
428  }
429
430  // No path or no root.
431  return StringRef();
432}
433
434const StringRef relative_path(StringRef path) {
435  StringRef root = root_path(path);
436  return path.substr(root.size());
437}
438
439void append(SmallVectorImpl<char> &path, const Twine &a,
440                                         const Twine &b,
441                                         const Twine &c,
442                                         const Twine &d) {
443  SmallString<32> a_storage;
444  SmallString<32> b_storage;
445  SmallString<32> c_storage;
446  SmallString<32> d_storage;
447
448  SmallVector<StringRef, 4> components;
449  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
450  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
451  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
452  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
453
454  for (SmallVectorImpl<StringRef>::const_iterator i = components.begin(),
455                                                  e = components.end();
456                                                  i != e; ++i) {
457    bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
458    bool component_has_sep = !i->empty() && is_separator((*i)[0]);
459    bool is_root_name = has_root_name(*i);
460
461    if (path_has_sep) {
462      // Strip separators from beginning of component.
463      size_t loc = i->find_first_not_of(separators);
464      StringRef c = i->substr(loc);
465
466      // Append it.
467      path.append(c.begin(), c.end());
468      continue;
469    }
470
471    if (!component_has_sep && !(path.empty() || is_root_name)) {
472      // Add a separator.
473      path.push_back(preferred_separator);
474    }
475
476    path.append(i->begin(), i->end());
477  }
478}
479
480void append(SmallVectorImpl<char> &path,
481            const_iterator begin, const_iterator end) {
482  for (; begin != end; ++begin)
483    path::append(path, *begin);
484}
485
486const StringRef parent_path(StringRef path) {
487  size_t end_pos = parent_path_end(path);
488  if (end_pos == StringRef::npos)
489    return StringRef();
490  else
491    return path.substr(0, end_pos);
492}
493
494void remove_filename(SmallVectorImpl<char> &path) {
495  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
496  if (end_pos != StringRef::npos)
497    path.set_size(end_pos);
498}
499
500void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
501  StringRef p(path.begin(), path.size());
502  SmallString<32> ext_storage;
503  StringRef ext = extension.toStringRef(ext_storage);
504
505  // Erase existing extension.
506  size_t pos = p.find_last_of('.');
507  if (pos != StringRef::npos && pos >= filename_pos(p))
508    path.set_size(pos);
509
510  // Append '.' if needed.
511  if (ext.size() > 0 && ext[0] != '.')
512    path.push_back('.');
513
514  // Append extension.
515  path.append(ext.begin(), ext.end());
516}
517
518void native(const Twine &path, SmallVectorImpl<char> &result) {
519  assert((!path.isSingleStringRef() ||
520          path.getSingleStringRef().data() != result.data()) &&
521         "path and result are not allowed to overlap!");
522  // Clear result.
523  result.clear();
524  path.toVector(result);
525  native(result);
526}
527
528void native(SmallVectorImpl<char> &path) {
529#ifdef LLVM_ON_WIN32
530  std::replace(path.begin(), path.end(), '/', '\\');
531#endif
532}
533
534const StringRef filename(StringRef path) {
535  return *(--end(path));
536}
537
538const StringRef stem(StringRef path) {
539  StringRef fname = filename(path);
540  size_t pos = fname.find_last_of('.');
541  if (pos == StringRef::npos)
542    return fname;
543  else
544    if ((fname.size() == 1 && fname == ".") ||
545        (fname.size() == 2 && fname == ".."))
546      return fname;
547    else
548      return fname.substr(0, pos);
549}
550
551const StringRef extension(StringRef path) {
552  StringRef fname = filename(path);
553  size_t pos = fname.find_last_of('.');
554  if (pos == StringRef::npos)
555    return StringRef();
556  else
557    if ((fname.size() == 1 && fname == ".") ||
558        (fname.size() == 2 && fname == ".."))
559      return StringRef();
560    else
561      return fname.substr(pos);
562}
563
564bool is_separator(char value) {
565  switch(value) {
566#ifdef LLVM_ON_WIN32
567    case '\\': // fall through
568#endif
569    case '/': return true;
570    default: return false;
571  }
572}
573
574static const char preferred_separator_string[] = { preferred_separator, '\0' };
575
576const StringRef get_separator() {
577  return preferred_separator_string;
578}
579
580void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
581  result.clear();
582
583#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
584  // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
585  // macros defined in <unistd.h> on darwin >= 9
586  int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
587                               : _CS_DARWIN_USER_CACHE_DIR;
588  size_t ConfLen = confstr(ConfName, nullptr, 0);
589  if (ConfLen > 0) {
590    do {
591      result.resize(ConfLen);
592      ConfLen = confstr(ConfName, result.data(), result.size());
593    } while (ConfLen > 0 && ConfLen != result.size());
594
595    if (ConfLen > 0) {
596      assert(result.back() == 0);
597      result.pop_back();
598      return;
599    }
600
601    result.clear();
602  }
603#endif
604
605  // Check whether the temporary directory is specified by an environment
606  // variable.
607  const char *EnvironmentVariable;
608#ifdef LLVM_ON_WIN32
609  EnvironmentVariable = "TEMP";
610#else
611  EnvironmentVariable = "TMPDIR";
612#endif
613  if (char *RequestedDir = getenv(EnvironmentVariable)) {
614    result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
615    return;
616  }
617
618  // Fall back to a system default.
619  const char *DefaultResult;
620#ifdef LLVM_ON_WIN32
621  (void)erasedOnReboot;
622  DefaultResult = "C:\\TEMP";
623#else
624  if (erasedOnReboot)
625    DefaultResult = "/tmp";
626  else
627    DefaultResult = "/var/tmp";
628#endif
629  result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
630}
631
632bool has_root_name(const Twine &path) {
633  SmallString<128> path_storage;
634  StringRef p = path.toStringRef(path_storage);
635
636  return !root_name(p).empty();
637}
638
639bool has_root_directory(const Twine &path) {
640  SmallString<128> path_storage;
641  StringRef p = path.toStringRef(path_storage);
642
643  return !root_directory(p).empty();
644}
645
646bool has_root_path(const Twine &path) {
647  SmallString<128> path_storage;
648  StringRef p = path.toStringRef(path_storage);
649
650  return !root_path(p).empty();
651}
652
653bool has_relative_path(const Twine &path) {
654  SmallString<128> path_storage;
655  StringRef p = path.toStringRef(path_storage);
656
657  return !relative_path(p).empty();
658}
659
660bool has_filename(const Twine &path) {
661  SmallString<128> path_storage;
662  StringRef p = path.toStringRef(path_storage);
663
664  return !filename(p).empty();
665}
666
667bool has_parent_path(const Twine &path) {
668  SmallString<128> path_storage;
669  StringRef p = path.toStringRef(path_storage);
670
671  return !parent_path(p).empty();
672}
673
674bool has_stem(const Twine &path) {
675  SmallString<128> path_storage;
676  StringRef p = path.toStringRef(path_storage);
677
678  return !stem(p).empty();
679}
680
681bool has_extension(const Twine &path) {
682  SmallString<128> path_storage;
683  StringRef p = path.toStringRef(path_storage);
684
685  return !extension(p).empty();
686}
687
688bool is_absolute(const Twine &path) {
689  SmallString<128> path_storage;
690  StringRef p = path.toStringRef(path_storage);
691
692  bool rootDir = has_root_directory(p),
693#ifdef LLVM_ON_WIN32
694       rootName = has_root_name(p);
695#else
696       rootName = true;
697#endif
698
699  return rootDir && rootName;
700}
701
702bool is_relative(const Twine &path) {
703  return !is_absolute(path);
704}
705
706} // end namespace path
707
708namespace fs {
709
710std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
711  file_status Status;
712  std::error_code EC = status(Path, Status);
713  if (EC)
714    return EC;
715  Result = Status.getUniqueID();
716  return std::error_code();
717}
718
719std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
720                                 SmallVectorImpl<char> &ResultPath,
721                                 unsigned Mode) {
722  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
723}
724
725std::error_code createUniqueFile(const Twine &Model,
726                                 SmallVectorImpl<char> &ResultPath) {
727  int Dummy;
728  return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
729}
730
731static std::error_code
732createTemporaryFile(const Twine &Model, int &ResultFD,
733                    llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
734  SmallString<128> Storage;
735  StringRef P = Model.toNullTerminatedStringRef(Storage);
736  assert(P.find_first_of(separators) == StringRef::npos &&
737         "Model must be a simple filename.");
738  // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
739  return createUniqueEntity(P.begin(), ResultFD, ResultPath,
740                            true, owner_read | owner_write, Type);
741}
742
743static std::error_code
744createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
745                    llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
746  const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
747  return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
748                             Type);
749}
750
751std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
752                                    int &ResultFD,
753                                    SmallVectorImpl<char> &ResultPath) {
754  return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
755}
756
757std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
758                                    SmallVectorImpl<char> &ResultPath) {
759  int Dummy;
760  return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
761}
762
763
764// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
765// for consistency. We should try using mkdtemp.
766std::error_code createUniqueDirectory(const Twine &Prefix,
767                                      SmallVectorImpl<char> &ResultPath) {
768  int Dummy;
769  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
770                            true, 0, FS_Dir);
771}
772
773std::error_code make_absolute(SmallVectorImpl<char> &path) {
774  StringRef p(path.data(), path.size());
775
776  bool rootDirectory = path::has_root_directory(p),
777#ifdef LLVM_ON_WIN32
778       rootName = path::has_root_name(p);
779#else
780       rootName = true;
781#endif
782
783  // Already absolute.
784  if (rootName && rootDirectory)
785    return std::error_code();
786
787  // All of the following conditions will need the current directory.
788  SmallString<128> current_dir;
789  if (std::error_code ec = current_path(current_dir))
790    return ec;
791
792  // Relative path. Prepend the current directory.
793  if (!rootName && !rootDirectory) {
794    // Append path to the current directory.
795    path::append(current_dir, p);
796    // Set path to the result.
797    path.swap(current_dir);
798    return std::error_code();
799  }
800
801  if (!rootName && rootDirectory) {
802    StringRef cdrn = path::root_name(current_dir);
803    SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
804    path::append(curDirRootName, p);
805    // Set path to the result.
806    path.swap(curDirRootName);
807    return std::error_code();
808  }
809
810  if (rootName && !rootDirectory) {
811    StringRef pRootName      = path::root_name(p);
812    StringRef bRootDirectory = path::root_directory(current_dir);
813    StringRef bRelativePath  = path::relative_path(current_dir);
814    StringRef pRelativePath  = path::relative_path(p);
815
816    SmallString<128> res;
817    path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
818    path.swap(res);
819    return std::error_code();
820  }
821
822  llvm_unreachable("All rootName and rootDirectory combinations should have "
823                   "occurred above!");
824}
825
826std::error_code create_directories(const Twine &Path, bool IgnoreExisting) {
827  SmallString<128> PathStorage;
828  StringRef P = Path.toStringRef(PathStorage);
829
830  // Be optimistic and try to create the directory
831  std::error_code EC = create_directory(P, IgnoreExisting);
832  // If we succeeded, or had any error other than the parent not existing, just
833  // return it.
834  if (EC != errc::no_such_file_or_directory)
835    return EC;
836
837  // We failed because of a no_such_file_or_directory, try to create the
838  // parent.
839  StringRef Parent = path::parent_path(P);
840  if (Parent.empty())
841    return EC;
842
843  if ((EC = create_directories(Parent)))
844      return EC;
845
846  return create_directory(P, IgnoreExisting);
847}
848
849std::error_code copy_file(const Twine &From, const Twine &To) {
850  int ReadFD, WriteFD;
851  if (std::error_code EC = openFileForRead(From, ReadFD))
852    return EC;
853  if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
854    close(ReadFD);
855    return EC;
856  }
857
858  const size_t BufSize = 4096;
859  char *Buf = new char[BufSize];
860  int BytesRead = 0, BytesWritten = 0;
861  for (;;) {
862    BytesRead = read(ReadFD, Buf, BufSize);
863    if (BytesRead <= 0)
864      break;
865    while (BytesRead) {
866      BytesWritten = write(WriteFD, Buf, BytesRead);
867      if (BytesWritten < 0)
868        break;
869      BytesRead -= BytesWritten;
870    }
871    if (BytesWritten < 0)
872      break;
873  }
874  close(ReadFD);
875  close(WriteFD);
876  delete[] Buf;
877
878  if (BytesRead < 0 || BytesWritten < 0)
879    return std::error_code(errno, std::generic_category());
880  return std::error_code();
881}
882
883bool exists(file_status status) {
884  return status_known(status) && status.type() != file_type::file_not_found;
885}
886
887bool status_known(file_status s) {
888  return s.type() != file_type::status_error;
889}
890
891bool is_directory(file_status status) {
892  return status.type() == file_type::directory_file;
893}
894
895std::error_code is_directory(const Twine &path, bool &result) {
896  file_status st;
897  if (std::error_code ec = status(path, st))
898    return ec;
899  result = is_directory(st);
900  return std::error_code();
901}
902
903bool is_regular_file(file_status status) {
904  return status.type() == file_type::regular_file;
905}
906
907std::error_code is_regular_file(const Twine &path, bool &result) {
908  file_status st;
909  if (std::error_code ec = status(path, st))
910    return ec;
911  result = is_regular_file(st);
912  return std::error_code();
913}
914
915bool is_other(file_status status) {
916  return exists(status) &&
917         !is_regular_file(status) &&
918         !is_directory(status);
919}
920
921void directory_entry::replace_filename(const Twine &filename, file_status st) {
922  SmallString<128> path(Path.begin(), Path.end());
923  path::remove_filename(path);
924  path::append(path, filename);
925  Path = path.str();
926  Status = st;
927}
928
929/// @brief Identify the magic in magic.
930file_magic identify_magic(StringRef Magic) {
931  if (Magic.size() < 4)
932    return file_magic::unknown;
933  switch ((unsigned char)Magic[0]) {
934    case 0x00: {
935      // COFF short import library file
936      if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
937          Magic[3] == (char)0xff)
938        return file_magic::coff_import_library;
939      // Windows resource file
940      const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
941      if (Magic.size() >= sizeof(Expected) &&
942          memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
943        return file_magic::windows_resource;
944      // 0x0000 = COFF unknown machine type
945      if (Magic[1] == 0)
946        return file_magic::coff_object;
947      break;
948    }
949    case 0xDE:  // 0x0B17C0DE = BC wraper
950      if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
951          Magic[3] == (char)0x0B)
952        return file_magic::bitcode;
953      break;
954    case 'B':
955      if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
956        return file_magic::bitcode;
957      break;
958    case '!':
959      if (Magic.size() >= 8)
960        if (memcmp(Magic.data(),"!<arch>\n",8) == 0)
961          return file_magic::archive;
962      break;
963
964    case '\177':
965      if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
966          Magic[3] == 'F') {
967        bool Data2MSB = Magic[5] == 2;
968        unsigned high = Data2MSB ? 16 : 17;
969        unsigned low  = Data2MSB ? 17 : 16;
970        if (Magic[high] == 0)
971          switch (Magic[low]) {
972            default: break;
973            case 1: return file_magic::elf_relocatable;
974            case 2: return file_magic::elf_executable;
975            case 3: return file_magic::elf_shared_object;
976            case 4: return file_magic::elf_core;
977          }
978      }
979      break;
980
981    case 0xCA:
982      if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
983          Magic[3] == char(0xBE)) {
984        // This is complicated by an overlap with Java class files.
985        // See the Mach-O section in /usr/share/file/magic for details.
986        if (Magic.size() >= 8 && Magic[7] < 43)
987          return file_magic::macho_universal_binary;
988      }
989      break;
990
991      // The two magic numbers for mach-o are:
992      // 0xfeedface - 32-bit mach-o
993      // 0xfeedfacf - 64-bit mach-o
994    case 0xFE:
995    case 0xCE:
996    case 0xCF: {
997      uint16_t type = 0;
998      if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
999          Magic[2] == char(0xFA) &&
1000          (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
1001        /* Native endian */
1002        if (Magic.size() >= 16) type = Magic[14] << 8 | Magic[15];
1003      } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
1004                 Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
1005                 Magic[3] == char(0xFE)) {
1006        /* Reverse endian */
1007        if (Magic.size() >= 14) type = Magic[13] << 8 | Magic[12];
1008      }
1009      switch (type) {
1010        default: break;
1011        case 1: return file_magic::macho_object;
1012        case 2: return file_magic::macho_executable;
1013        case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
1014        case 4: return file_magic::macho_core;
1015        case 5: return file_magic::macho_preload_executable;
1016        case 6: return file_magic::macho_dynamically_linked_shared_lib;
1017        case 7: return file_magic::macho_dynamic_linker;
1018        case 8: return file_magic::macho_bundle;
1019        case 9: return file_magic::macho_dynamic_linker;
1020        case 10: return file_magic::macho_dsym_companion;
1021      }
1022      break;
1023    }
1024    case 0xF0: // PowerPC Windows
1025    case 0x83: // Alpha 32-bit
1026    case 0x84: // Alpha 64-bit
1027    case 0x66: // MPS R4000 Windows
1028    case 0x50: // mc68K
1029    case 0x4c: // 80386 Windows
1030    case 0xc4: // ARMNT Windows
1031      if (Magic[1] == 0x01)
1032        return file_magic::coff_object;
1033
1034    case 0x90: // PA-RISC Windows
1035    case 0x68: // mc68K Windows
1036      if (Magic[1] == 0x02)
1037        return file_magic::coff_object;
1038      break;
1039
1040    case 0x4d: // Possible MS-DOS stub on Windows PE file
1041      if (Magic[1] == 0x5a) {
1042        uint32_t off =
1043          *reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
1044        // PE/COFF file, either EXE or DLL.
1045        if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
1046          return file_magic::pecoff_executable;
1047      }
1048      break;
1049
1050    case 0x64: // x86-64 Windows.
1051      if (Magic[1] == char(0x86))
1052        return file_magic::coff_object;
1053      break;
1054
1055    default:
1056      break;
1057  }
1058  return file_magic::unknown;
1059}
1060
1061std::error_code identify_magic(const Twine &Path, file_magic &Result) {
1062  int FD;
1063  if (std::error_code EC = openFileForRead(Path, FD))
1064    return EC;
1065
1066  char Buffer[32];
1067  int Length = read(FD, Buffer, sizeof(Buffer));
1068  if (close(FD) != 0 || Length < 0)
1069    return std::error_code(errno, std::generic_category());
1070
1071  Result = identify_magic(StringRef(Buffer, Length));
1072  return std::error_code();
1073}
1074
1075std::error_code directory_entry::status(file_status &result) const {
1076  return fs::status(Path, result);
1077}
1078
1079} // end namespace fs
1080} // end namespace sys
1081} // end namespace llvm
1082
1083// Include the truly platform-specific parts.
1084#if defined(LLVM_ON_UNIX)
1085#include "Unix/Path.inc"
1086#endif
1087#if defined(LLVM_ON_WIN32)
1088#include "Windows/Path.inc"
1089#endif
1090