1dda28197Spatrick //===-- FileSystemPosix.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Host/FileSystem.h"
10061da546Spatrick
11061da546Spatrick // C includes
12061da546Spatrick #include <dirent.h>
13061da546Spatrick #include <fcntl.h>
14061da546Spatrick #include <sys/mount.h>
15061da546Spatrick #include <sys/param.h>
16061da546Spatrick #include <sys/stat.h>
17061da546Spatrick #include <sys/types.h>
18061da546Spatrick #include <unistd.h>
19061da546Spatrick #if defined(__NetBSD__)
20061da546Spatrick #include <sys/statvfs.h>
21061da546Spatrick #endif
22061da546Spatrick
23061da546Spatrick // lldb Includes
24061da546Spatrick #include "lldb/Host/Host.h"
25061da546Spatrick #include "lldb/Utility/Status.h"
26061da546Spatrick #include "lldb/Utility/StreamString.h"
27061da546Spatrick
28061da546Spatrick #include "llvm/Support/Errno.h"
29061da546Spatrick #include "llvm/Support/FileSystem.h"
30061da546Spatrick
31061da546Spatrick using namespace lldb;
32061da546Spatrick using namespace lldb_private;
33061da546Spatrick
34061da546Spatrick const char *FileSystem::DEV_NULL = "/dev/null";
35061da546Spatrick
Symlink(const FileSpec & src,const FileSpec & dst)36061da546Spatrick Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
37061da546Spatrick Status error;
38*f6aab3d8Srobert if (::symlink(dst.GetPath().c_str(), src.GetPath().c_str()) == -1)
39061da546Spatrick error.SetErrorToErrno();
40061da546Spatrick return error;
41061da546Spatrick }
42061da546Spatrick
Readlink(const FileSpec & src,FileSpec & dst)43061da546Spatrick Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
44061da546Spatrick Status error;
45061da546Spatrick char buf[PATH_MAX];
46dda28197Spatrick ssize_t count = ::readlink(src.GetPath().c_str(), buf, sizeof(buf) - 1);
47061da546Spatrick if (count < 0)
48061da546Spatrick error.SetErrorToErrno();
49061da546Spatrick else {
50061da546Spatrick buf[count] = '\0'; // Success
51061da546Spatrick dst.SetFile(buf, FileSpec::Style::native);
52061da546Spatrick }
53061da546Spatrick return error;
54061da546Spatrick }
55061da546Spatrick
ResolveSymbolicLink(const FileSpec & src,FileSpec & dst)56061da546Spatrick Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
57061da546Spatrick char resolved_path[PATH_MAX];
58061da546Spatrick if (!src.GetPath(resolved_path, sizeof(resolved_path))) {
59*f6aab3d8Srobert return Status("Couldn't get the canonical path for %s",
60*f6aab3d8Srobert src.GetPath().c_str());
61061da546Spatrick }
62061da546Spatrick
63061da546Spatrick char real_path[PATH_MAX + 1];
64061da546Spatrick if (realpath(resolved_path, real_path) == nullptr) {
65061da546Spatrick Status err;
66061da546Spatrick err.SetErrorToErrno();
67061da546Spatrick return err;
68061da546Spatrick }
69061da546Spatrick
70061da546Spatrick dst = FileSpec(real_path);
71061da546Spatrick
72061da546Spatrick return Status();
73061da546Spatrick }
74061da546Spatrick
Fopen(const char * path,const char * mode)75061da546Spatrick FILE *FileSystem::Fopen(const char *path, const char *mode) {
76061da546Spatrick return llvm::sys::RetryAfterSignal(nullptr, ::fopen, path, mode);
77061da546Spatrick }
78061da546Spatrick
Open(const char * path,int flags,int mode)79061da546Spatrick int FileSystem::Open(const char *path, int flags, int mode) {
80061da546Spatrick return llvm::sys::RetryAfterSignal(-1, ::open, path, flags, mode);
81061da546Spatrick }
82