1 //===- llvm/Support/Unix/PathV2.cpp - Unix Path Implementation --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Unix specific implementation of the PathV2 API.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 //=== WARNING: Implementation here must contain only generic UNIX code that
16 //=== is guaranteed to work on *all* UNIX variants.
17 //===----------------------------------------------------------------------===//
27 #include <sys/types.h>
34 AutoFD(int fd) : FileDescriptor(fd) {}
36 if (FileDescriptor >= 0)
37 ::close(FileDescriptor);
41 int ret = FileDescriptor;
46 operator int() const {return FileDescriptor;}
54 error_code current_path(SmallVectorImpl<char> &result) {
55 long size = ::pathconf(".", _PC_PATH_MAX);
56 result.reserve(size + 1);
57 result.set_size(size + 1);
59 if (::getcwd(result.data(), result.size()) == 0)
60 return error_code(errno, system_category());
62 result.set_size(strlen(result.data()));
63 return make_error_code(errc::success);
66 } // end namespace path
70 error_code copy_file(const Twine &from, const Twine &to, copy_option copt) {
72 SmallString<128> from_storage;
73 SmallString<128> to_storage;
74 StringRef f = from.toNullTerminatedStringRef(from_storage);
75 StringRef t = to.toNullTerminatedStringRef(to_storage);
77 const size_t buf_sz = 32768;
79 int from_file = -1, to_file = -1;
82 if ((from_file = ::open(f.begin(), O_RDONLY)) < 0)
83 return error_code(errno, system_category());
84 AutoFD from_fd(from_file);
87 struct stat from_stat;
88 if (::stat(f.begin(), &from_stat) != 0)
89 return error_code(errno, system_category());
92 int to_flags = O_CREAT | O_WRONLY;
93 if (copt == copy_option::fail_if_exists)
97 if ((to_file = ::open(t.begin(), to_flags, from_stat.st_mode)) < 0)
98 return error_code(errno, system_category());
99 AutoFD to_fd(to_file);
102 ssize_t sz, sz_read = 1, sz_write;
103 while (sz_read > 0 &&
104 (sz_read = ::read(from_fd, buffer, buf_sz)) > 0) {
105 // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
106 // Marc Rochkind, Addison-Wesley, 2004, page 94
109 if ((sz = ::write(to_fd, buffer + sz_write, sz_read - sz_write)) < 0) {
110 sz_read = sz; // cause read loop termination.
114 } while (sz_write < sz_read);
117 // After all the file operations above the return value of close actually
119 if (::close(from_fd.take()) < 0) sz_read = -1;
120 if (::close(to_fd.take()) < 0) sz_read = -1;
124 return error_code(errno, system_category());
126 return make_error_code(errc::success);
129 } // end namespace fs
130 } // end namespace sys
131 } // end namespace llvm