xref: /freebsd/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h (revision 6e75b2fbf9a03e6876e0a3c089e0b3ad71876125)
1  //===- llvm/Support/Unix/Unix.h - Common Unix Include File -------*- C++ -*-===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This file defines things specific to Unix implementations.
10  //
11  //===----------------------------------------------------------------------===//
12  
13  #ifndef LLVM_LIB_SUPPORT_UNIX_UNIX_H
14  #define LLVM_LIB_SUPPORT_UNIX_UNIX_H
15  
16  //===----------------------------------------------------------------------===//
17  //=== WARNING: Implementation here must contain only generic UNIX code that
18  //===          is guaranteed to work on all UNIX variants.
19  //===----------------------------------------------------------------------===//
20  
21  #include "llvm/Config/config.h"
22  #include "llvm/Support/Chrono.h"
23  #include "llvm/Support/Errno.h"
24  #include "llvm/Support/ErrorHandling.h"
25  #include <algorithm>
26  #include <assert.h>
27  #include <cerrno>
28  #include <cstdio>
29  #include <cstdlib>
30  #include <cstring>
31  #include <string>
32  #include <sys/types.h>
33  #include <sys/wait.h>
34  
35  #ifdef HAVE_UNISTD_H
36  #include <unistd.h>
37  #endif
38  
39  #ifdef HAVE_SYS_TIME_H
40  # include <sys/time.h>
41  #endif
42  #include <time.h>
43  
44  #ifdef HAVE_DLFCN_H
45  # include <dlfcn.h>
46  #endif
47  
48  #ifdef HAVE_FCNTL_H
49  # include <fcntl.h>
50  #endif
51  
52  /// This function builds an error message into \p ErrMsg using the \p prefix
53  /// string and the Unix error number given by \p errnum. If errnum is -1, the
54  /// default then the value of errno is used.
55  /// Make an error message
56  ///
57  /// If the error number can be converted to a string, it will be
58  /// separated from prefix by ": ".
59  static inline bool MakeErrMsg(
60    std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
61    if (!ErrMsg)
62      return true;
63    if (errnum == -1)
64      errnum = errno;
65    *ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
66    return true;
67  }
68  
69  // Include StrError(errnum) in a fatal error message.
70  LLVM_ATTRIBUTE_NORETURN static inline void ReportErrnumFatal(const char *Msg,
71                                                               int errnum) {
72    std::string ErrMsg;
73    MakeErrMsg(&ErrMsg, Msg, errnum);
74    llvm::report_fatal_error(ErrMsg);
75  }
76  
77  namespace llvm {
78  namespace sys {
79  
80  /// Convert a struct timeval to a duration. Note that timeval can be used both
81  /// as a time point and a duration. Be sure to check what the input represents.
82  inline std::chrono::microseconds toDuration(const struct timeval &TV) {
83    return std::chrono::seconds(TV.tv_sec) +
84           std::chrono::microseconds(TV.tv_usec);
85  }
86  
87  /// Convert a time point to struct timespec.
88  inline struct timespec toTimeSpec(TimePoint<> TP) {
89    using namespace std::chrono;
90  
91    struct timespec RetVal;
92    RetVal.tv_sec = toTimeT(TP);
93    RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count();
94    return RetVal;
95  }
96  
97  /// Convert a time point to struct timeval.
98  inline struct timeval toTimeVal(TimePoint<std::chrono::microseconds> TP) {
99    using namespace std::chrono;
100  
101    struct timeval RetVal;
102    RetVal.tv_sec = toTimeT(TP);
103    RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count();
104    return RetVal;
105  }
106  
107  } // namespace sys
108  } // namespace llvm
109  
110  #endif
111