diff --git a/libc/utils/UnitTest/CMakeLists.txt b/libc/utils/UnitTest/CMakeLists.txt index 9c7b48aea4f9..1c9753e62a59 100644 --- a/libc/utils/UnitTest/CMakeLists.txt +++ b/libc/utils/UnitTest/CMakeLists.txt @@ -1,9 +1,8 @@ add_llvm_library( LibcUnitTest Test.cpp Test.h - LINK_COMPONENTS Support ) target_include_directories(LibcUnitTest PUBLIC ${LIBC_SOURCE_DIR}) add_dependencies(LibcUnitTest libc.utils.CPP.standalone_cpp) target_link_libraries(LibcUnitTest PUBLIC libc_test_utils) diff --git a/libc/utils/testutils/CMakeLists.txt b/libc/utils/testutils/CMakeLists.txt index 80c23f4b0769..70237ddc1f8d 100644 --- a/libc/utils/testutils/CMakeLists.txt +++ b/libc/utils/testutils/CMakeLists.txt @@ -1,16 +1,14 @@ if(CMAKE_HOST_UNIX) set(EFFile ExecuteFunctionUnix.cpp) set(FDReaderFile FDReaderUnix.cpp) endif() add_llvm_library( libc_test_utils StreamWrapper.cpp StreamWrapper.h ${EFFile} ExecuteFunction.h ${FDReaderFile} FDReader.h - LINK_COMPONENTS - Support ) diff --git a/libc/utils/testutils/ExecuteFunctionUnix.cpp b/libc/utils/testutils/ExecuteFunctionUnix.cpp index 60e367a40cb6..4050a0ca8a6e 100644 --- a/libc/utils/testutils/ExecuteFunctionUnix.cpp +++ b/libc/utils/testutils/ExecuteFunctionUnix.cpp @@ -1,83 +1,84 @@ //===-- ExecuteFunction implementation for Unix-like Systems --------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "ExecuteFunction.h" -#include "llvm/Support/raw_ostream.h" #include #include +#include +#include #include #include #include #include #include namespace __llvm_libc { namespace testutils { bool ProcessStatus::exitedNormally() const { return WIFEXITED(PlatformDefined); } int ProcessStatus::getExitCode() const { assert(exitedNormally() && "Abnormal termination, no exit code"); return WEXITSTATUS(PlatformDefined); } int ProcessStatus::getFatalSignal() const { if (exitedNormally()) return 0; return WTERMSIG(PlatformDefined); } ProcessStatus invokeInSubprocess(FunctionCaller *Func, unsigned timeoutMS) { std::unique_ptr X(Func); int pipeFDs[2]; if (::pipe(pipeFDs) == -1) return ProcessStatus::Error("pipe(2) failed"); // Don't copy the buffers into the child process and print twice. - llvm::outs().flush(); - llvm::errs().flush(); + std::cout.flush(); + std::cerr.flush(); pid_t Pid = ::fork(); if (Pid == -1) return ProcessStatus::Error("fork(2) failed"); if (!Pid) { (*Func)(); std::exit(0); } ::close(pipeFDs[1]); struct pollfd pollFD { pipeFDs[0], 0, 0 }; // No events requested so this call will only return after the timeout or if // the pipes peer was closed, signaling the process exited. if (::poll(&pollFD, 1, timeoutMS) == -1) return ProcessStatus::Error("poll(2) failed"); // If the pipe wasn't closed by the child yet then timeout has expired. if (!(pollFD.revents & POLLHUP)) { ::kill(Pid, SIGKILL); return ProcessStatus::TimedOut(); } int WStatus = 0; // Wait on the pid of the subprocess here so it gets collected by the system // and doesn't turn into a zombie. pid_t status = ::waitpid(Pid, &WStatus, 0); if (status == -1) return ProcessStatus::Error("waitpid(2) failed"); assert(status == Pid); (void)status; return {WStatus}; } const char *signalAsString(int Signum) { return ::strsignal(Signum); } } // namespace testutils } // namespace __llvm_libc diff --git a/libc/utils/testutils/FDReaderUnix.cpp b/libc/utils/testutils/FDReaderUnix.cpp index c54a1a423d86..db1f63f0dcc3 100644 --- a/libc/utils/testutils/FDReaderUnix.cpp +++ b/libc/utils/testutils/FDReaderUnix.cpp @@ -1,41 +1,53 @@ //===-- FDReader.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "FDReader.h" -#include "llvm/Support/MemoryBuffer.h" #include #include +#include #include namespace __llvm_libc { namespace testutils { FDReader::FDReader() { - if (::pipe(pipefd)) - llvm::report_fatal_error("pipe(2) failed"); + if (::pipe(pipefd)) { + std::cerr << "pipe(2) failed"; + abort(); + } } FDReader::~FDReader() { ::close(pipefd[0]); ::close(pipefd[1]); } bool FDReader::matchWritten(const char *str) { - llvm::ErrorOr> bufOrErr = - llvm::MemoryBuffer::getOpenFile(pipefd[0], "", - /* FileSize (irrelevant) */ 0); - if (!bufOrErr) { - assert(0 && "Error reading from pipe"); - return false; + + ::close(pipefd[1]); + + constexpr ssize_t ChunkSize = 4096 * 4; + + char Buffer[ChunkSize]; + std::string PipeStr; + std::string InputStr(str); + + for (int BytesRead; (BytesRead = ::read(pipefd[0], Buffer, ChunkSize));) { + if (BytesRead > 0) { + PipeStr.insert(PipeStr.size(), Buffer, BytesRead); + } else { + assert(0 && "Error reading from pipe"); + return false; + } } - const llvm::MemoryBuffer &buf = **bufOrErr; - return !std::strncmp(buf.getBufferStart(), str, buf.getBufferSize()); + + return PipeStr == InputStr; } } // namespace testutils } // namespace __llvm_libc diff --git a/libc/utils/testutils/StreamWrapper.cpp b/libc/utils/testutils/StreamWrapper.cpp index f6318a993401..9071ebca245c 100644 --- a/libc/utils/testutils/StreamWrapper.cpp +++ b/libc/utils/testutils/StreamWrapper.cpp @@ -1,48 +1,48 @@ //===-- StreamWrapper.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "StreamWrapper.h" -#include "llvm/Support/raw_ostream.h" #include +#include #include #include namespace __llvm_libc { namespace testutils { -StreamWrapper outs() { return {std::addressof(llvm::outs())}; } +StreamWrapper outs() { return {std::addressof(std::cout)}; } template StreamWrapper &StreamWrapper::operator<<(T t) { assert(OS); - llvm::raw_ostream &Stream = *reinterpret_cast(OS); + std::ostream &Stream = *reinterpret_cast(OS); Stream << t; return *this; } template StreamWrapper &StreamWrapper::operator<<(void *t); template StreamWrapper &StreamWrapper::operator<<(const char *t); template StreamWrapper &StreamWrapper::operator<<(char *t); template StreamWrapper &StreamWrapper::operator<<(char t); template StreamWrapper &StreamWrapper::operator<<(short t); template StreamWrapper &StreamWrapper::operator<<(int t); template StreamWrapper &StreamWrapper::operator<<(long t); template StreamWrapper &StreamWrapper::operator<<(long long t); template StreamWrapper & StreamWrapper::operator<<(unsigned char t); template StreamWrapper & StreamWrapper::operator<<(unsigned short t); template StreamWrapper &StreamWrapper::operator<<(unsigned int t); template StreamWrapper & StreamWrapper::operator<<(unsigned long t); template StreamWrapper & StreamWrapper::operator<<(unsigned long long t); template StreamWrapper &StreamWrapper::operator<<(bool t); template StreamWrapper &StreamWrapper::operator<<(std::string t); } // namespace testutils } // namespace __llvm_libc