xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
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 Andric inline 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 Andric inline 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 Andric inline 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