aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/Unix
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-07-27 23:34:35 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-23 18:26:01 +0000
commit0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch)
tree6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Support/Unix
parent6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff)
parentac9a064cb179f3425b310fa2847f8764ac970a4d (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/Unix')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc10
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Path.inc78
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Process.inc95
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Program.inc18
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc2
-rw-r--r--contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc7
6 files changed, 99 insertions, 111 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc
index 69bd1164343d..bac208a7d543 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc
@@ -86,7 +86,7 @@ MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
#else
fd = open("/dev/zero", O_RDWR);
if (fd == -1) {
- EC = std::error_code(errno, std::generic_category());
+ EC = errnoAsErrorCode();
return MemoryBlock();
}
#endif
@@ -122,7 +122,7 @@ MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
return allocateMappedMemory(NumBytes, nullptr, PFlags, EC);
}
- EC = std::error_code(errno, std::generic_category());
+ EC = errnoAsErrorCode();
#if !defined(MAP_ANON)
close(fd);
#endif
@@ -153,7 +153,7 @@ std::error_code Memory::releaseMappedMemory(MemoryBlock &M) {
return std::error_code();
if (0 != ::munmap(M.Address, M.AllocatedSize))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
M.Address = nullptr;
M.AllocatedSize = 0;
@@ -186,7 +186,7 @@ std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
if (InvalidateCache && !(Protect & PROT_READ)) {
int Result = ::mprotect((void *)Start, End - Start, Protect | PROT_READ);
if (Result != 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
Memory::InvalidateInstructionCache(M.Address, M.AllocatedSize);
InvalidateCache = false;
@@ -196,7 +196,7 @@ std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
int Result = ::mprotect((void *)Start, End - Start, Protect);
if (Result != 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
if (InvalidateCache)
Memory::InvalidateInstructionCache(M.Address, M.AllocatedSize);
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc
index 9f89d63bb0fd..cf05db546e02 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc
@@ -357,7 +357,7 @@ uint32_t file_status::getLinkCount() const { return fs_st_nlinks; }
ErrorOr<space_info> disk_space(const Twine &Path) {
struct STATVFS Vfs;
if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
auto FrSize = STATVFS_F_FRSIZE(Vfs);
space_info SpaceInfo;
SpaceInfo.capacity = static_cast<uint64_t>(Vfs.f_blocks) * FrSize;
@@ -386,7 +386,7 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
// See if there was a real error.
if (errno != ENOMEM) {
result.clear();
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
// Otherwise there just wasn't enough space.
result.resize_for_overwrite(result.capacity() * 2);
@@ -403,7 +403,7 @@ std::error_code set_current_path(const Twine &path) {
StringRef p = path.toNullTerminatedStringRef(path_storage);
if (::chdir(p.begin()) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -415,7 +415,7 @@ std::error_code create_directory(const Twine &path, bool IgnoreExisting,
if (::mkdir(p.begin(), Perms) == -1) {
if (errno != EEXIST || !IgnoreExisting)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
return std::error_code();
@@ -431,7 +431,7 @@ std::error_code create_link(const Twine &to, const Twine &from) {
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::symlink(t.begin(), f.begin()) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -444,7 +444,7 @@ std::error_code create_hard_link(const Twine &to, const Twine &from) {
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::link(t.begin(), f.begin()) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -456,7 +456,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
struct stat buf;
if (lstat(p.begin(), &buf) != 0) {
if (errno != ENOENT || !IgnoreNonExisting)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -470,7 +470,7 @@ std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
if (::remove(p.begin()) == -1) {
if (errno != ENOENT || !IgnoreNonExisting)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
return std::error_code();
@@ -516,7 +516,7 @@ static bool is_local_impl(struct STATVFS &Vfs) {
// target
StringRef fstype(Vfs.f_basetype);
// NFS is the only non-local fstype??
- return !fstype.equals("nfs");
+ return fstype != "nfs";
#elif defined(_AIX)
// Call mntctl; try more than twice in case of timing issues with a concurrent
// mount.
@@ -563,7 +563,7 @@ static bool is_local_impl(struct STATVFS &Vfs) {
std::error_code is_local(const Twine &Path, bool &Result) {
struct STATVFS Vfs;
if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
Result = is_local_impl(Vfs);
return std::error_code();
@@ -572,7 +572,7 @@ std::error_code is_local(const Twine &Path, bool &Result) {
std::error_code is_local(int FD, bool &Result) {
struct STATVFS Vfs;
if (::FSTATVFS(FD, &Vfs))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
Result = is_local_impl(Vfs);
return std::error_code();
@@ -586,7 +586,7 @@ std::error_code rename(const Twine &from, const Twine &to) {
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::rename(f.begin(), t.begin()) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -595,7 +595,7 @@ std::error_code resize_file(int FD, uint64_t Size) {
// Use ftruncate as a fallback. It may or may not allocate space. At least on
// OS X with HFS+ it does.
if (::ftruncate(FD, Size) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -617,7 +617,7 @@ std::error_code access(const Twine &Path, AccessMode Mode) {
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
if (::access(P.begin(), convertAccessMode(Mode)) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
if (Mode == AccessMode::Execute) {
// Don't say that directories are executable.
@@ -726,7 +726,7 @@ static file_type typeForMode(mode_t Mode) {
static std::error_code fillStatus(int StatRet, const struct stat &Status,
file_status &Result) {
if (StatRet != 0) {
- std::error_code EC(errno, std::generic_category());
+ std::error_code EC = errnoAsErrorCode();
if (EC == errc::no_such_file_or_directory)
Result = file_status(file_type::file_not_found);
else
@@ -782,13 +782,13 @@ std::error_code setPermissions(const Twine &Path, perms Permissions) {
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
if (::chmod(P.begin(), Permissions))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
std::error_code setPermissions(int FD, perms Permissions) {
if (::fchmod(FD, Permissions))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -799,7 +799,7 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
Times[0] = sys::toTimeSpec(AccessTime);
Times[1] = sys::toTimeSpec(ModificationTime);
if (::futimens(FD, Times))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
#elif defined(HAVE_FUTIMES)
timeval Times[2];
@@ -809,7 +809,7 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
sys::toTimeVal(std::chrono::time_point_cast<std::chrono::microseconds>(
ModificationTime));
if (::futimes(FD, Times))
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
#elif defined(__MVS__)
attrib_t Attr;
@@ -819,7 +819,7 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
Attr.att_mtimechg = 1;
Attr.att_mtime = sys::toTimeT(ModificationTime);
if (::__fchattr(FD, &Attr, sizeof(Attr)) != 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
#else
#warning Missing futimes() and futimens()
@@ -858,7 +858,7 @@ std::error_code mapped_file_region::init(int FD, uint64_t Offset,
Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset);
if (Mapping == MAP_FAILED)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -897,7 +897,7 @@ std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
SmallString<128> path_null(path);
DIR *directory = ::opendir(path_null.c_str());
if (!directory)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
it.IterationHandle = reinterpret_cast<intptr_t>(directory);
// Add something for replace_filename to replace.
@@ -932,7 +932,7 @@ std::error_code detail::directory_iterator_increment(detail::DirIterState &It) {
errno = 0;
dirent *CurDir = ::readdir(reinterpret_cast<DIR *>(It.IterationHandle));
if (CurDir == nullptr && errno != 0) {
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
} else if (CurDir != nullptr) {
StringRef Name(CurDir->d_name);
if ((Name.size() == 1 && Name[0] == '.') ||
@@ -1023,7 +1023,7 @@ std::error_code openFile(const Twine &Name, int &ResultFD,
// when open is overloaded, such as in Bionic.
auto Open = [&]() { return ::open(P.begin(), OpenFlags, Mode); };
if ((ResultFD = sys::RetryAfterSignal(-1, Open)) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
#ifndef O_CLOEXEC
if (!(Flags & OF_ChildInherit)) {
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
@@ -1087,10 +1087,10 @@ std::error_code openFile(const Twine &Name, int &ResultFD,
* open().
*/
if ((Flags & OF_Append) && lseek(ResultFD, 0, SEEK_END) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
struct stat Stat;
if (fstat(ResultFD, &Stat) == -1)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
if (S_ISREG(Stat.st_mode)) {
bool DoSetTag = (Access & FA_Write) && (Disp != CD_OpenExisting) &&
!Stat.st_tag.ft_txtflag && !Stat.st_tag.ft_ccsid &&
@@ -1190,7 +1190,16 @@ Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) {
#endif
ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
if (ssize_t(NumRead) == -1)
- return errorCodeToError(std::error_code(errno, std::generic_category()));
+ return errorCodeToError(errnoAsErrorCode());
+// The underlying operation on these platforms allow opening directories
+// for reading in more cases than other platforms.
+#if defined(__MVS__) || defined(_AIX)
+ struct stat Status;
+ if (fstat(FD, &Status) == -1)
+ return errorCodeToError(errnoAsErrorCode());
+ if (S_ISDIR(Status.st_mode))
+ return errorCodeToError(make_error_code(errc::is_a_directory));
+#endif
return NumRead;
}
@@ -1206,11 +1215,11 @@ Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf,
sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Size, Offset);
#else
if (lseek(FD, Offset, SEEK_SET) == -1)
- return errorCodeToError(std::error_code(errno, std::generic_category()));
+ return errorCodeToError(errnoAsErrorCode());
ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
#endif
if (NumRead == -1)
- return errorCodeToError(std::error_code(errno, std::generic_category()));
+ return errorCodeToError(errnoAsErrorCode());
return NumRead;
}
@@ -1243,8 +1252,7 @@ std::error_code lockFile(int FD) {
Lock.l_len = 0;
if (::fcntl(FD, F_SETLKW, &Lock) != -1)
return std::error_code();
- int Error = errno;
- return std::error_code(Error, std::generic_category());
+ return errnoAsErrorCode();
}
std::error_code unlockFile(int FD) {
@@ -1255,7 +1263,7 @@ std::error_code unlockFile(int FD) {
Lock.l_len = 0;
if (::fcntl(FD, F_SETLK, &Lock) != -1)
return std::error_code();
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
std::error_code closeFile(file_t &F) {
@@ -1321,7 +1329,7 @@ std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
StringRef P = path.toNullTerminatedStringRef(Storage);
char Buffer[PATH_MAX];
if (::realpath(P.begin(), Buffer) == nullptr)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
dest.append(Buffer, Buffer + strlen(Buffer));
return std::error_code();
}
@@ -1330,7 +1338,7 @@ std::error_code changeFileOwnership(int FD, uint32_t Owner, uint32_t Group) {
auto FChown = [&]() { return ::fchown(FD, Owner, Group); };
// Retry if fchown call fails due to interruption.
if ((sys::RetryAfterSignal(-1, FChown)) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
return std::error_code();
}
@@ -1513,7 +1521,7 @@ std::error_code copy_file(const Twine &From, const Twine &To) {
#endif
if (!copyfile(FromS.c_str(), ToS.c_str(), /*State=*/NULL, COPYFILE_DATA))
return std::error_code();
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
#endif // __APPLE__
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc
index a003596e8c02..cf62ede9ae27 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc
@@ -86,7 +86,7 @@ Expected<unsigned> Process::getPageSize() {
#error Cannot get the page size on this machine
#endif
if (page_size == -1)
- return errorCodeToError(std::error_code(errno, std::generic_category()));
+ return errorCodeToError(errnoAsErrorCode());
return static_cast<unsigned>(page_size);
}
@@ -143,7 +143,26 @@ void Process::GetTimeUsage(TimePoint<> &elapsed,
void Process::PreventCoreFiles() {
#if HAVE_SETRLIMIT
struct rlimit rlim;
- rlim.rlim_cur = rlim.rlim_max = 0;
+ getrlimit(RLIMIT_CORE, &rlim);
+#ifdef __linux__
+ // On Linux, if the kernel.core_pattern sysctl starts with a '|' (i.e. it
+ // is being piped to a coredump handler such as systemd-coredumpd), the
+ // kernel ignores RLIMIT_CORE (since we aren't creating a file in the file
+ // system) except for the magic value of 1, which disables coredumps when
+ // piping. 1 byte is too small for any kind of valid core dump, so it
+ // also disables coredumps if kernel.core_pattern creates files directly.
+ // While most piped coredump handlers do respect the crashing processes'
+ // RLIMIT_CORE, this is notable not the case for Debian's systemd-coredump
+ // due to a local patch that changes sysctl.d/50-coredump.conf to ignore
+ // the specified limit and instead use RLIM_INFINITY.
+ //
+ // The alternative to using RLIMIT_CORE=1 would be to use prctl() with the
+ // PR_SET_DUMPABLE flag, however that also prevents ptrace(), so makes it
+ // impossible to attach a debugger.
+ rlim.rlim_cur = std::min<rlim_t>(1, rlim.rlim_max);
+#else
+ rlim.rlim_cur = 0;
+#endif
setrlimit(RLIMIT_CORE, &rlim);
#endif
@@ -216,7 +235,7 @@ std::error_code Process::FixupStandardFileDescriptors() {
assert(errno && "expected errno to be set if fstat failed!");
// fstat should return EBADF if the file descriptor is closed.
if (errno != EBADF)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
// if fstat succeeds, move on to the next FD.
if (!errno)
@@ -228,13 +247,13 @@ std::error_code Process::FixupStandardFileDescriptors() {
// RetryAfterSignal when open is overloaded, such as in Bionic.
auto Open = [&]() { return ::open("/dev/null", O_RDWR); };
if ((NullFD = RetryAfterSignal(-1, Open)) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
if (NullFD == StandardFD)
FDC.keepOpen();
else if (dup2(NullFD, StandardFD) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
}
return std::error_code();
}
@@ -262,7 +281,7 @@ std::error_code Process::SafelyCloseFileDescriptor(int FD) {
// Create a signal set filled with *all* signals.
sigset_t FullSet, SavedSet;
if (sigfillset(&FullSet) < 0 || sigfillset(&SavedSet) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
// Atomically swap our current signal mask with a full mask.
#if LLVM_ENABLE_THREADS
@@ -270,7 +289,7 @@ std::error_code Process::SafelyCloseFileDescriptor(int FD) {
return std::error_code(EC, std::generic_category());
#else
if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0)
- return std::error_code(errno, std::generic_category());
+ return errnoAsErrorCode();
#endif
// Attempt to close the file descriptor.
// We need to save the error, if one occurs, because our subsequent call to
@@ -342,17 +361,9 @@ unsigned Process::StandardErrColumns() {
return getColumns();
}
-#ifdef LLVM_ENABLE_TERMINFO
-// We manually declare these extern functions because finding the correct
-// headers from various terminfo, curses, or other sources is harder than
-// writing their specs down.
-extern "C" int setupterm(char *term, int filedes, int *errret);
-extern "C" struct term *set_curterm(struct term *termp);
-extern "C" int del_curterm(struct term *termp);
-extern "C" int tigetnum(char *capname);
-#endif
-
-bool checkTerminalEnvironmentForColors() {
+static bool terminalHasColors() {
+ // Check if the current terminal is one of terminals that are known to support
+ // ANSI color escape codes.
if (const char *TermStr = std::getenv("TERM")) {
return StringSwitch<bool>(TermStr)
.Case("ansi", true)
@@ -369,54 +380,10 @@ bool checkTerminalEnvironmentForColors() {
return false;
}
-static bool terminalHasColors(int fd) {
-#ifdef LLVM_ENABLE_TERMINFO
- // First, acquire a global lock because these C routines are thread hostile.
- static std::mutex TermColorMutex;
- std::lock_guard<std::mutex> G(TermColorMutex);
-
- struct term *previous_term = set_curterm(nullptr);
- int errret = 0;
- if (setupterm(nullptr, fd, &errret) != 0)
- // Regardless of why, if we can't get terminfo, we shouldn't try to print
- // colors.
- return false;
-
- // Test whether the terminal as set up supports color output. How to do this
- // isn't entirely obvious. We can use the curses routine 'has_colors' but it
- // would be nice to avoid a dependency on curses proper when we can make do
- // with a minimal terminfo parsing library. Also, we don't really care whether
- // the terminal supports the curses-specific color changing routines, merely
- // if it will interpret ANSI color escape codes in a reasonable way. Thus, the
- // strategy here is just to query the baseline colors capability and if it
- // supports colors at all to assume it will translate the escape codes into
- // whatever range of colors it does support. We can add more detailed tests
- // here if users report them as necessary.
- //
- // The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
- // the terminfo says that no colors are supported.
- int colors_ti = tigetnum(const_cast<char *>("colors"));
- bool HasColors =
- colors_ti >= 0 ? colors_ti : checkTerminalEnvironmentForColors();
-
- // Now extract the structure allocated by setupterm and free its memory
- // through a really silly dance.
- struct term *termp = set_curterm(previous_term);
- (void)del_curterm(termp); // Drop any errors here.
-
- // Return true if we found a color capabilities for the current terminal.
- return HasColors;
-#else
- // When the terminfo database is not available, check if the current terminal
- // is one of terminals that are known to support ANSI color escape codes.
- return checkTerminalEnvironmentForColors();
-#endif
-}
-
bool Process::FileDescriptorHasColors(int fd) {
// A file descriptor has colors if it is displayed and the terminal has
// colors.
- return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
+ return FileDescriptorIsDisplayed(fd) && terminalHasColors();
}
bool Process::StandardOutHasColors() {
@@ -437,7 +404,7 @@ bool Process::ColorNeedsFlush() {
}
const char *Process::OutputColor(char code, bool bold, bool bg) {
- return colorcodes[bg ? 1 : 0][bold ? 1 : 0][code & 7];
+ return colorcodes[bg ? 1 : 0][bold ? 1 : 0][code & 15];
}
const char *Process::OutputBold(bool bg) { return "\033[1m"; }
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc
index 5d9757bcc51b..2742734bb11e 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc
@@ -173,10 +173,11 @@ toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
}
static bool Execute(ProcessInfo &PI, StringRef Program,
- ArrayRef<StringRef> Args, std::optional<ArrayRef<StringRef>> Env,
+ ArrayRef<StringRef> Args,
+ std::optional<ArrayRef<StringRef>> Env,
ArrayRef<std::optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg,
- BitVector *AffinityMask) {
+ BitVector *AffinityMask, bool DetachProcess) {
if (!llvm::sys::fs::exists(Program)) {
if (ErrMsg)
*ErrMsg = std::string("Executable \"") + Program.str() +
@@ -202,7 +203,8 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
// If this OS has posix_spawn and there is no memory limit being implied, use
// posix_spawn. It is more efficient than fork/exec.
#ifdef HAVE_POSIX_SPAWN
- if (MemoryLimit == 0) {
+ // Cannot use posix_spawn if you would like to detach the process
+ if (MemoryLimit == 0 && !DetachProcess) {
posix_spawn_file_actions_t FileActionsStore;
posix_spawn_file_actions_t *FileActions = nullptr;
@@ -270,7 +272,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
return true;
}
-#endif
+#endif // HAVE_POSIX_SPAWN
// Create a child process.
int child = fork();
@@ -307,6 +309,14 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
}
}
+ if (DetachProcess) {
+ // Detach from controlling terminal
+ if (::setsid() == -1) {
+ MakeErrMsg(ErrMsg, "Could not detach process, ::setsid failed");
+ return false;
+ }
+ }
+
// Set memory limits
if (MemoryLimit != 0) {
SetMemoryLimits(MemoryLimit);
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc
index 792b0fd66b45..298fde1a387c 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc
@@ -289,7 +289,7 @@ static void CreateSigAltStack() {}
static void RegisterHandlers() { // Not signal-safe.
// The mutex prevents other threads from registering handlers while we're
// doing it. We also have to protect the handlers and their count because
- // a signal handler could fire while we're registeting handlers.
+ // a signal handler could fire while we're registering handlers.
static ManagedStatic<sys::SmartMutex<true>> SignalHandlerRegistrationMutex;
sys::SmartScopedLock<true> Guard(*SignalHandlerRegistrationMutex);
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc
index 55e7dcfa4678..839c00c5ebbf 100644
--- a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc
+++ b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc
@@ -115,8 +115,11 @@ uint64_t llvm::get_threadid() {
// Calling "mach_thread_self()" bumps the reference count on the thread
// port, so we need to deallocate it. mach_task_self() doesn't bump the ref
// count.
- thread_port_t Self = mach_thread_self();
- mach_port_deallocate(mach_task_self(), Self);
+ static thread_local thread_port_t Self = [] {
+ thread_port_t InitSelf = mach_thread_self();
+ mach_port_deallocate(mach_task_self(), Self);
+ return InitSelf;
+ }();
return Self;
#elif defined(__FreeBSD__)
return uint64_t(pthread_getthreadid_np());