75 lines · cpp
1//===-- FileSystemPosix.cpp -----------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Host/FileSystem.h"10 11// C includes12#include <fcntl.h>13#include <unistd.h>14 15// lldb Includes16#include "lldb/Host/Host.h"17#include "lldb/Utility/Status.h"18#include "lldb/Utility/StreamString.h"19 20#include "llvm/Support/Errno.h"21#include "llvm/Support/FileSystem.h"22 23using namespace lldb;24using namespace lldb_private;25 26const char *FileSystem::DEV_NULL = "/dev/null";27 28Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {29 Status error;30 if (::symlink(dst.GetPath().c_str(), src.GetPath().c_str()) == -1)31 return Status::FromErrno();32 return error;33}34 35Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {36 Status error;37 char buf[PATH_MAX];38 ssize_t count = ::readlink(src.GetPath().c_str(), buf, sizeof(buf) - 1);39 if (count < 0)40 return Status::FromErrno();41 42 buf[count] = '\0'; // Success43 dst.SetFile(buf, FileSpec::Style::native);44 45 return error;46}47 48Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {49 char resolved_path[PATH_MAX];50 if (!src.GetPath(resolved_path, sizeof(resolved_path))) {51 return Status::FromErrorStringWithFormat(52 "Couldn't get the canonical path for %s", src.GetPath().c_str());53 }54 55 char real_path[PATH_MAX + 1];56 if (realpath(resolved_path, real_path) == nullptr) {57 return Status::FromErrno();58 }59 60 dst = FileSpec(real_path);61 62 return Status();63}64 65FILE *FileSystem::Fopen(const char *path, const char *mode) {66 return llvm::sys::RetryAfterSignal(nullptr, ::fopen, path, mode);67}68 69int FileSystem::Open(const char *path, int flags, int mode) {70 // Call ::open in a lambda to avoid overload resolution in RetryAfterSignal71 // when open is overloaded, such as in Bionic.72 auto lambda = [&]() { return ::open(path, flags, mode); };73 return llvm::sys::RetryAfterSignal(-1, lambda);74}75