diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:01 +0000 |
| commit | 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch) | |
| tree | 6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Support/Unix | |
| parent | 6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff) | |
| parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/Unix')
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()); |
