summaryrefslogtreecommitdiff
path: root/lib/System/Unix/Unix.h
blob: 0f9b96adca092e642bc00f70f4b4f788fe3ee3ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//===- llvm/System/Unix/Unix.h - Common Unix Include File -------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines things specific to Unix implementations.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SYSTEM_UNIX_UNIX_H
#define LLVM_SYSTEM_UNIX_UNIX_H

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//===          is guaranteed to work on all UNIX variants.
//===----------------------------------------------------------------------===//

#include "llvm/Config/config.h"     // Get autoconf configuration settings
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <string>
#include <algorithm>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif

#ifdef HAVE_ASSERT_H
#include <assert.h>
#endif

#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif

#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif

#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif

inline bool GetErrno(const std::string &prefix, std::string *ErrDest,
                     int errnum = -1) {
  char buffer[MAXPATHLEN];
  
  if (ErrDest == 0) return true;
  
  buffer[0] = 0;
  if (errnum == -1)
    errnum = errno;
#ifdef HAVE_STRERROR_R
  // strerror_r is thread-safe.
  if (errnum)
    strerror_r(errnum, buffer, MAXPATHLEN-1);
#elif HAVE_STRERROR
  // Copy the thread un-safe result of strerror into
  // the buffer as fast as possible to minimize impact
  // of collision of strerror in multiple threads.
  if (errnum)
    strncpy(buffer, strerror(errnum), MAXPATHLEN-1);
  buffer[MAXPATHLEN-1] = 0;
#else
  // Strange that this system doesn't even have strerror
  // but, oh well, just use a generic message
  sprintf(buffer, "Error #%d", errnum);
#endif
  *ErrDest = prefix + ": " + buffer;
  return true;
}

inline void ThrowErrno(const std::string& prefix, int errnum = -1) {
  char buffer[MAXPATHLEN];
  buffer[0] = 0;
  if (errnum == -1)
    errnum = errno;
#ifdef HAVE_STRERROR_R
  // strerror_r is thread-safe.
  if (errnum)
    strerror_r(errnum,buffer,MAXPATHLEN-1);
#elif HAVE_STRERROR
  // Copy the thread un-safe result of strerror into
  // the buffer as fast as possible to minimize impact
  // of collision of strerror in multiple threads.
  if (errnum)
    strncpy(buffer,strerror(errnum),MAXPATHLEN-1);
  buffer[MAXPATHLEN-1] = 0;
#else
  // Strange that this system doesn't even have strerror
  // but, oh well, just use a generic message
  sprintf(buffer, "Error #%d", errnum);
#endif
  throw prefix + ": " + buffer;
}

/// This function builds an error message into \p ErrMsg using the \p prefix
/// string and the Unix error number given by \p errnum. If errnum is -1, the
/// default then the value of errno is used.
/// @brief Make an error message
inline bool MakeErrMsg(
  std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
  if (!ErrMsg)
    return true;
  char buffer[MAXPATHLEN];
  buffer[0] = 0;
  if (errnum == -1)
    errnum = errno;
#ifdef HAVE_STRERROR_R
  // strerror_r is thread-safe.
  if (errnum)
    strerror_r(errnum,buffer,MAXPATHLEN-1);
#elif HAVE_STRERROR
  // Copy the thread un-safe result of strerror into
  // the buffer as fast as possible to minimize impact
  // of collision of strerror in multiple threads.
  if (errnum)
    strncpy(buffer,strerror(errnum),MAXPATHLEN-1);
  buffer[MAXPATHLEN-1] = 0;
#else
  // Strange that this system doesn't even have strerror
  // but, oh well, just use a generic message
  sprintf(buffer, "Error #%d", errnum);
#endif
  *ErrMsg = buffer;
  return true;
}

#endif