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