10b57cec5SDimitry Andric //===- llvm/Support/Unix/Unix.h - Common Unix Include File -------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines things specific to Unix implementations. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_SUPPORT_UNIX_UNIX_H 140b57cec5SDimitry Andric #define LLVM_LIB_SUPPORT_UNIX_UNIX_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only generic UNIX code that 180b57cec5SDimitry Andric //=== is guaranteed to work on all UNIX variants. 190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #include "llvm/Config/config.h" 220b57cec5SDimitry Andric #include "llvm/Support/Chrono.h" 230b57cec5SDimitry Andric #include "llvm/Support/Errno.h" 24480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 250b57cec5SDimitry Andric #include <algorithm> 260b57cec5SDimitry Andric #include <assert.h> 270b57cec5SDimitry Andric #include <cerrno> 280b57cec5SDimitry Andric #include <cstdio> 290b57cec5SDimitry Andric #include <cstdlib> 300b57cec5SDimitry Andric #include <cstring> 310b57cec5SDimitry Andric #include <string> 320b57cec5SDimitry Andric #include <sys/types.h> 330b57cec5SDimitry Andric #include <sys/wait.h> 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric #ifdef HAVE_UNISTD_H 360b57cec5SDimitry Andric #include <unistd.h> 370b57cec5SDimitry Andric #endif 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric #ifdef HAVE_SYS_TIME_H 400b57cec5SDimitry Andric # include <sys/time.h> 410b57cec5SDimitry Andric #endif 420b57cec5SDimitry Andric #include <time.h> 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric #ifdef HAVE_DLFCN_H 450b57cec5SDimitry Andric # include <dlfcn.h> 460b57cec5SDimitry Andric #endif 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric #ifdef HAVE_FCNTL_H 490b57cec5SDimitry Andric # include <fcntl.h> 500b57cec5SDimitry Andric #endif 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric /// This function builds an error message into \p ErrMsg using the \p prefix 530b57cec5SDimitry Andric /// string and the Unix error number given by \p errnum. If errnum is -1, the 540b57cec5SDimitry Andric /// default then the value of errno is used. 550b57cec5SDimitry Andric /// Make an error message 560b57cec5SDimitry Andric /// 570b57cec5SDimitry Andric /// If the error number can be converted to a string, it will be 580b57cec5SDimitry Andric /// separated from prefix by ": ". 590b57cec5SDimitry Andric static inline bool MakeErrMsg( 600b57cec5SDimitry Andric std::string* ErrMsg, const std::string& prefix, int errnum = -1) { 610b57cec5SDimitry Andric if (!ErrMsg) 620b57cec5SDimitry Andric return true; 630b57cec5SDimitry Andric if (errnum == -1) 640b57cec5SDimitry Andric errnum = errno; 650b57cec5SDimitry Andric *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum); 660b57cec5SDimitry Andric return true; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 69480093f4SDimitry Andric // Include StrError(errnum) in a fatal error message. ReportErrnumFatal(const char * Msg,int errnum)70*349cc55cSDimitry Andric[[noreturn]] static inline void ReportErrnumFatal(const char *Msg, int errnum) { 71480093f4SDimitry Andric std::string ErrMsg; 72480093f4SDimitry Andric MakeErrMsg(&ErrMsg, Msg, errnum); 73*349cc55cSDimitry Andric llvm::report_fatal_error(llvm::Twine(ErrMsg)); 74480093f4SDimitry Andric } 75480093f4SDimitry Andric 760b57cec5SDimitry Andric namespace llvm { 770b57cec5SDimitry Andric namespace sys { 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric /// Convert a struct timeval to a duration. Note that timeval can be used both 800b57cec5SDimitry Andric /// as a time point and a duration. Be sure to check what the input represents. toDuration(const struct timeval & TV)810b57cec5SDimitry Andricinline std::chrono::microseconds toDuration(const struct timeval &TV) { 820b57cec5SDimitry Andric return std::chrono::seconds(TV.tv_sec) + 830b57cec5SDimitry Andric std::chrono::microseconds(TV.tv_usec); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric /// Convert a time point to struct timespec. toTimeSpec(TimePoint<> TP)870b57cec5SDimitry Andricinline struct timespec toTimeSpec(TimePoint<> TP) { 880b57cec5SDimitry Andric using namespace std::chrono; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric struct timespec RetVal; 910b57cec5SDimitry Andric RetVal.tv_sec = toTimeT(TP); 920b57cec5SDimitry Andric RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count(); 930b57cec5SDimitry Andric return RetVal; 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// Convert a time point to struct timeval. toTimeVal(TimePoint<std::chrono::microseconds> TP)970b57cec5SDimitry Andricinline struct timeval toTimeVal(TimePoint<std::chrono::microseconds> TP) { 980b57cec5SDimitry Andric using namespace std::chrono; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric struct timeval RetVal; 1010b57cec5SDimitry Andric RetVal.tv_sec = toTimeT(TP); 1020b57cec5SDimitry Andric RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count(); 1030b57cec5SDimitry Andric return RetVal; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric } // namespace sys 1070b57cec5SDimitry Andric } // namespace llvm 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric #endif 110