29 #ifdef HAVE_SYS_MMAN_H
34 # define NAMLEN(dirent) strlen((dirent)->d_name)
36 # define dirent direct
37 # define NAMLEN(dirent) (dirent)->d_namlen
39 # include <sys/ndir.h>
50 #include <mach-o/dyld.h>
60 #if defined(__GNU__) && !defined(PATH_MAX)
61 # define PATH_MAX 4096
75 AutoFD(
int fd) : FileDescriptor(fd) {}
77 if (FileDescriptor >= 0)
78 ::close(FileDescriptor);
82 int ret = FileDescriptor;
87 operator int()
const {
return FileDescriptor;}
104 result.
append(d.begin(), d.end());
111 bool MakeAbsolute,
unsigned Mode,
123 ModelStorage.
swap(TDir);
129 ResultPath = ModelStorage;
136 for (
unsigned i = 0, e = ModelStorage.
size(); i != e; ++i) {
137 if (ModelStorage[i] ==
'%')
144 int RandomFD =
::open(ResultPath.
begin(), O_RDWR | O_CREAT | O_EXCL, Mode);
145 if (RandomFD == -1) {
146 int SavedErrno = errno;
149 goto retry_random_path;
163 goto retry_random_path;
173 goto retry_random_path;
183 #if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
184 defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
185 defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__)
187 test_dir(
char buf[PATH_MAX],
char ret[PATH_MAX],
188 const char *dir,
const char *bin)
192 snprintf(buf, PATH_MAX,
"%s/%s", dir, bin);
195 if (
stat(buf, &sb) != 0)
202 getprogpath(
char ret[PATH_MAX],
const char *bin)
204 char *pv, *s, *t, buf[PATH_MAX];
208 if (test_dir(buf, ret,
"/", bin) == 0)
214 if (
strchr(bin,
'/') != NULL) {
215 if (getcwd(buf, PATH_MAX) == NULL)
217 if (test_dir(buf, ret, buf, bin) == 0)
223 if ((pv =
getenv(
"PATH")) == NULL)
228 while ((t = strsep(&s,
":")) != NULL) {
229 if (test_dir(buf, ret, t, bin) == 0) {
237 #endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
242 #if defined(__APPLE__)
246 char exe_path[MAXPATHLEN];
247 uint32_t size =
sizeof(exe_path);
248 if (_NSGetExecutablePath(exe_path, &size) == 0) {
249 char link_path[MAXPATHLEN];
253 #elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
254 defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
255 defined(__FreeBSD_kernel__)
256 char exe_path[PATH_MAX];
258 if (getprogpath(exe_path, argv0) != NULL)
260 #elif defined(__linux__) || defined(__CYGWIN__)
261 char exe_path[MAXPATHLEN];
265 ssize_t len =
readlink(aPath.str().c_str(), exe_path,
sizeof(exe_path));
270 if (getprogpath(exe_path, argv0) != NULL)
273 #elif defined(HAVE_DLFCN_H)
276 int err = dladdr(MainAddr, &DLInfo);
282 char link_path[MAXPATHLEN];
283 if (
realpath(DLInfo.dli_fname, link_path))
286 #error GetMainExecutable is not implemented on this host yet.
293 Ret.fromEpochTime(fs_st_mtime);
298 return UniqueID(fs_st_dev, fs_st_ino);
340 if (::
mkdir(p.
begin(), S_IRWXU | S_IRWXG) == -1) {
393 if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode))
396 if (::
remove(p.
begin()) == -1) {
423 if (::truncate(p.
begin(), size) == -1)
458 if (!S_ISREG(buf.st_mode))
465 return A.fs_st_dev == B.fs_st_dev &&
466 A.fs_st_ino == B.fs_st_ino;
470 file_status fsA, fsB;
478 file_status &Result) {
490 if (S_ISDIR(Status.st_mode))
492 else if (S_ISREG(Status.st_mode))
494 else if (S_ISBLK(Status.st_mode))
496 else if (S_ISCHR(Status.st_mode))
498 else if (S_ISFIFO(Status.st_mode))
500 else if (S_ISSOCK(Status.st_mode))
503 perms Perms =
static_cast<perms>(Status.st_mode);
505 file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_mtime,
506 Status.st_uid, Status.st_gid, Status.st_size);
517 return fillStatus(StatRet, Status, Result);
522 int StatRet =
::fstat(FD, &Status);
523 return fillStatus(StatRet, Status, Result);
527 #if defined(HAVE_FUTIMENS)
529 Times[0].tv_sec = Time.toPosixTime();
530 Times[0].tv_nsec = 0;
532 if (::futimens(FD, Times))
533 #elif defined(HAVE_FUTIMES)
535 Times[0].tv_sec = Time.toPosixTime();
536 Times[0].tv_usec = 0;
538 if (::futimes(FD, Times))
540 #error Missing futimes() and futimens()
555 uint64_t FileSize =
FileInfo.st_size;
559 else if (FileSize < Size) {
561 if (ftruncate(FD, Size) == -1)
565 #if !defined(__minix)
568 int flags = MAP_PRIVATE;
570 int prot = (Mode ==
readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
574 Mapping = ::mmap(0, Size, prot, flags, FD, Offset);
575 if (Mapping == MAP_FAILED)
580 mapped_file_region::mapped_file_region(
const Twine &path,
589 if (length > std::numeric_limits<size_t>::max()) {
596 int oflags = (mode == readonly) ? O_RDONLY : O_RDWR;
603 ec =
init(ofd,
true, offset);
608 mapped_file_region::mapped_file_region(
int fd,
618 if (length > std::numeric_limits<size_t>::max()) {
623 ec =
init(fd, closefd, offset);
628 mapped_file_region::~mapped_file_region() {
630 ::munmap(Mapping, Size);
633 #if LLVM_HAS_RVALUE_REFERENCES
634 mapped_file_region::mapped_file_region(mapped_file_region &&other)
635 : Mode(other.Mode), Size(other.Size), Mapping(other.Mapping) {
640 mapped_file_region::mapmode mapped_file_region::flags()
const {
641 assert(Mapping &&
"Mapping failed but used anyway!");
645 uint64_t mapped_file_region::size()
const {
646 assert(Mapping &&
"Mapping failed but used anyway!");
650 char *mapped_file_region::data()
const {
651 assert(Mapping &&
"Mapping failed but used anyway!");
652 assert(Mode != readonly &&
"Cannot get non const data for readonly mapping!");
653 return reinterpret_cast<char*
>(Mapping);
656 const char *mapped_file_region::const_data()
const {
657 assert(Mapping &&
"Mapping failed but used anyway!");
658 return reinterpret_cast<const char*
>(Mapping);
661 int mapped_file_region::alignment() {
668 DIR *directory =
::opendir(path_null.c_str());
672 it.IterationHandle =
reinterpret_cast<intptr_t>(directory);
675 it.CurrentEntry = directory_entry(path_null.str());
680 if (it.IterationHandle)
681 ::closedir(reinterpret_cast<DIR *>(it.IterationHandle));
682 it.IterationHandle = 0;
683 it.CurrentEntry = directory_entry();
689 dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
690 if (cur_dir == 0 && errno != 0) {
692 }
else if (cur_dir != 0) {
693 StringRef name(cur_dir->d_name, NAMLEN(cur_dir));
694 if ((name.
size() == 1 && name[0] ==
'.') ||
695 (name.
size() == 2 && name[0] ==
'.' && name[1] ==
'.'))
697 it.CurrentEntry.replace_filename(name);
723 }
else if (size != len) {
736 bool map_writable,
void *&result) {
739 int oflags = map_writable ? O_RDWR : O_RDONLY;
744 #if !defined(__minix)
745 int flags = map_writable ? MAP_SHARED : MAP_PRIVATE;
747 int flags = MAP_PRIVATE;
749 int prot = map_writable ? (PROT_READ|PROT_WRITE) : PROT_READ;
753 result = ::mmap(0, size, prot, flags, fd, file_offset);
754 if (result == MAP_FAILED) {
762 if ( ::munmap(base, size) == -1 )
771 while ((ResultFD =
open(P.
begin(), O_RDONLY)) < 0) {
782 "Cannot specify both 'excl' and 'append' file creation flags!");
787 OpenFlags |= O_APPEND;
789 OpenFlags |= O_TRUNC;
void toVector(SmallVectorImpl< char > &Out) const
void set_size(unsigned N)
void push_back(const T &Elt)
bool can_execute(const Twine &Path)
Can we execute this file?
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
const error_category & system_category()
size_t size() const
size - Get the string size.
error_code directory_iterator_construct(DirIterState &, StringRef)
int fstat(int fildes, struct stat *buf);
error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags, unsigned Mode=0666)
error_code resize_file(const Twine &path, uint64_t size)
Resize path to size. File is resized as if by POSIX truncate().
int open(const char *path, int oflag, ... );
error_code setLastModificationAndAccessTime(int FD, TimeValue Time)
DIR *opendir(const char *dirname);.
UniqueID getUniqueID() const
error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
error_code unmap_file_pages(void *base, size_t size)
Memory unmaps the contents of a file.
error_code openFileForRead(const Twine &Name, int &ResultFD)
FILE *fopen(const char *filename, const char *mode);.
int fclose(FILE *stream);
bool status_known(file_status s)
Is status available?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
int access(const char *path, int amode);
#define llvm_unreachable(msg)
bool is_absolute(const Twine &path)
Is path absolute?
char *strchr(const char *s, int c);
May access map via data and modify it. Written to path.
error_code directory_iterator_destruct(DirIterState &)
error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, bool map_writable, void *&result)
Memory maps the contents of a file.
bool can_write(const Twine &Path)
Can we write this file?
error_code directory_iterator_increment(DirIterState &)
ssize_t readlink(const char *path, char *buf, size_t bufsize);
May only access map via const_data as read only.
const char * data() const
error_code create_hard_link(const Twine &to, const Twine &from)
Create a hard link from from to to.
std::string getMainExecutable(const char *argv0, void *MainExecAddr)
static llvm::error_code createUniqueEntity(const llvm::Twine &Model, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, unsigned Mode, FSEntity Type)
char *realpath(const char *file_name, char *resolved_name);
initializer< Ty > init(const Ty &Val)
error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
void swap(SmallVectorImpl &RHS)
int snprintf(char *s, size_t n, const char *format, ...);
int mkdir(const char *path, mode_t mode);
void append(in_iter in_start, in_iter in_end)
int stat(const char *path, struct stat *buf);
char *strdup(const char *s1);
static self_process * get_self()
Get the process object for the current process.
size_t strlen(const char *s);
static unsigned GetRandomNumber()
int ferror(FILE *stream);
pointer data()
data - Return a pointer to the vector's buffer, even if empty().
error_code create_directory(const Twine &path, bool &existed)
Create the directory in path.
error_code create_symlink(const Twine &to, const Twine &from)
Create a symbolic link from from to to.
static error_code success()
size_t page_size() const
Get the virtual memory page size.
bool equivalent(file_status A, file_status B)
Do file_status's represent the same thing?
StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
TimeValue getLastModificationTime() const
error_code rename(const Twine &from, const Twine &to)
Rename from to to. Files are renamed as if by POSIX rename().
bool exists(file_status status)
Does file exist?
char *getenv(const char *name);
error_code get_magic(const Twine &path, uint32_t len, SmallVectorImpl< char > &result)
Get path's first len bytes.
error_code make_error_code(errc _e)