Add getenv() wrapper that works on multibyte environment variable.
[oota-llvm.git] / lib / Support / Unix / Process.inc
1 //===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the generic Unix implementation of the Process class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Unix.h"
15 #include "llvm/ADT/Hashing.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/Mutex.h"
18 #include "llvm/Support/MutexGuard.h"
19 #include "llvm/Support/TimeValue.h"
20 #ifdef HAVE_SYS_TIME_H
21 #include <sys/time.h>
22 #endif
23 #ifdef HAVE_SYS_RESOURCE_H
24 #include <sys/resource.h>
25 #endif
26 // DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for
27 // <stdlib.h> instead. Unix.h includes this for us already.
28 #if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \
29     !defined(__OpenBSD__) && !defined(__Bitrig__)
30 #include <malloc.h>
31 #endif
32 #ifdef HAVE_MALLOC_MALLOC_H
33 #include <malloc/malloc.h>
34 #endif
35 #ifdef HAVE_SYS_IOCTL_H
36 #  include <sys/ioctl.h>
37 #endif
38 #ifdef HAVE_TERMIOS_H
39 #  include <termios.h>
40 #endif
41
42 //===----------------------------------------------------------------------===//
43 //=== WARNING: Implementation here must contain only generic UNIX code that
44 //===          is guaranteed to work on *all* UNIX variants.
45 //===----------------------------------------------------------------------===//
46
47 using namespace llvm;
48 using namespace sys;
49
50
51 process::id_type self_process::get_id() {
52   return getpid();
53 }
54
55 static std::pair<TimeValue, TimeValue> getRUsageTimes() {
56 #if defined(HAVE_GETRUSAGE)
57   struct rusage RU;
58   ::getrusage(RUSAGE_SELF, &RU);
59   return std::make_pair(
60       TimeValue(
61           static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
62           static_cast<TimeValue::NanoSecondsType>(
63               RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
64       TimeValue(
65           static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
66           static_cast<TimeValue::NanoSecondsType>(
67               RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
68 #else
69 #warning Cannot get usage times on this platform
70   return std::make_pair(TimeValue(), TimeValue());
71 #endif
72 }
73
74 TimeValue self_process::get_user_time() const {
75 #if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0
76   // Try to get a high resolution CPU timer.
77   struct timespec TS;
78   if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0)
79     return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec),
80                      static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec));
81 #endif
82
83   // Otherwise fall back to rusage based timing.
84   return getRUsageTimes().first;
85 }
86
87 TimeValue self_process::get_system_time() const {
88   // We can only collect system time by inspecting the results of getrusage.
89   return getRUsageTimes().second;
90 }
91
92 // On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
93 // offset in mmap(3) should be aligned to the AllocationGranularity.
94 static unsigned getPageSize() {
95 #if defined(HAVE_GETPAGESIZE)
96   const int page_size = ::getpagesize();
97 #elif defined(HAVE_SYSCONF)
98   long page_size = ::sysconf(_SC_PAGE_SIZE);
99 #else
100 #warning Cannot get the page size on this machine
101 #endif
102   return static_cast<unsigned>(page_size);
103 }
104
105 // This constructor guaranteed to be run exactly once on a single thread, and
106 // sets up various process invariants that can be queried cheaply from then on.
107 self_process::self_process() : PageSize(getPageSize()) {
108 }
109
110
111 size_t Process::GetMallocUsage() {
112 #if defined(HAVE_MALLINFO)
113   struct mallinfo mi;
114   mi = ::mallinfo();
115   return mi.uordblks;
116 #elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
117   malloc_statistics_t Stats;
118   malloc_zone_statistics(malloc_default_zone(), &Stats);
119   return Stats.size_in_use;   // darwin
120 #elif defined(HAVE_SBRK)
121   // Note this is only an approximation and more closely resembles
122   // the value returned by mallinfo in the arena field.
123   static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
124   char *EndOfMemory = (char*)sbrk(0);
125   if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
126     return EndOfMemory - StartOfMemory;
127   else
128     return 0;
129 #else
130 #warning Cannot get malloc info on this platform
131   return 0;
132 #endif
133 }
134
135 void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
136                            TimeValue &sys_time) {
137   elapsed = TimeValue::now();
138   llvm::tie(user_time, sys_time) = getRUsageTimes();
139 }
140
141 #if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
142 #include <mach/mach.h>
143 #endif
144
145 // Some LLVM programs such as bugpoint produce core files as a normal part of
146 // their operation. To prevent the disk from filling up, this function
147 // does what's necessary to prevent their generation.
148 void Process::PreventCoreFiles() {
149 #if HAVE_SETRLIMIT
150   struct rlimit rlim;
151   rlim.rlim_cur = rlim.rlim_max = 0;
152   setrlimit(RLIMIT_CORE, &rlim);
153 #endif
154
155 #if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
156   // Disable crash reporting on Mac OS X 10.0-10.4
157
158   // get information about the original set of exception ports for the task
159   mach_msg_type_number_t Count = 0;
160   exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
161   exception_port_t OriginalPorts[EXC_TYPES_COUNT];
162   exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
163   thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
164   kern_return_t err =
165     task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
166                              &Count, OriginalPorts, OriginalBehaviors,
167                              OriginalFlavors);
168   if (err == KERN_SUCCESS) {
169     // replace each with MACH_PORT_NULL.
170     for (unsigned i = 0; i != Count; ++i)
171       task_set_exception_ports(mach_task_self(), OriginalMasks[i],
172                                MACH_PORT_NULL, OriginalBehaviors[i],
173                                OriginalFlavors[i]);
174   }
175
176   // Disable crash reporting on Mac OS X 10.5
177   signal(SIGABRT, _exit);
178   signal(SIGILL,  _exit);
179   signal(SIGFPE,  _exit);
180   signal(SIGSEGV, _exit);
181   signal(SIGBUS,  _exit);
182 #endif
183 }
184
185 Optional<std::string> Process::GetEnv(StringRef Name) {
186   std::string NameStr = Name.str();
187   const char *Val = ::getenv(NameStr.c_str());
188   if (!Val)
189     return None;
190   return std::string(Val);
191 }
192
193 bool Process::StandardInIsUserInput() {
194   return FileDescriptorIsDisplayed(STDIN_FILENO);
195 }
196
197 bool Process::StandardOutIsDisplayed() {
198   return FileDescriptorIsDisplayed(STDOUT_FILENO);
199 }
200
201 bool Process::StandardErrIsDisplayed() {
202   return FileDescriptorIsDisplayed(STDERR_FILENO);
203 }
204
205 bool Process::FileDescriptorIsDisplayed(int fd) {
206 #if HAVE_ISATTY
207   return isatty(fd);
208 #else
209   // If we don't have isatty, just return false.
210   return false;
211 #endif
212 }
213
214 static unsigned getColumns(int FileID) {
215   // If COLUMNS is defined in the environment, wrap to that many columns.
216   if (const char *ColumnsStr = std::getenv("COLUMNS")) {
217     int Columns = std::atoi(ColumnsStr);
218     if (Columns > 0)
219       return Columns;
220   }
221
222   unsigned Columns = 0;
223
224 #if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
225   // Try to determine the width of the terminal.
226   struct winsize ws;
227   if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
228     Columns = ws.ws_col;
229 #endif
230
231   return Columns;
232 }
233
234 unsigned Process::StandardOutColumns() {
235   if (!StandardOutIsDisplayed())
236     return 0;
237
238   return getColumns(1);
239 }
240
241 unsigned Process::StandardErrColumns() {
242   if (!StandardErrIsDisplayed())
243     return 0;
244
245   return getColumns(2);
246 }
247
248 #ifdef HAVE_TERMINFO
249 // We manually declare these extern functions because finding the correct
250 // headers from various terminfo, curses, or other sources is harder than
251 // writing their specs down.
252 extern "C" int setupterm(char *term, int filedes, int *errret);
253 extern "C" struct term *set_curterm(struct term *termp);
254 extern "C" int del_curterm(struct term *termp);
255 extern "C" int tigetnum(char *capname);
256 #endif
257
258 static bool terminalHasColors(int fd) {
259 #ifdef HAVE_TERMINFO
260   // First, acquire a global lock because these C routines are thread hostile.
261   static sys::Mutex M;
262   MutexGuard G(M);
263
264   int errret = 0;
265   if (setupterm((char *)0, fd, &errret) != 0)
266     // Regardless of why, if we can't get terminfo, we shouldn't try to print
267     // colors.
268     return false;
269
270   // Test whether the terminal as set up supports color output. How to do this
271   // isn't entirely obvious. We can use the curses routine 'has_colors' but it
272   // would be nice to avoid a dependency on curses proper when we can make do
273   // with a minimal terminfo parsing library. Also, we don't really care whether
274   // the terminal supports the curses-specific color changing routines, merely
275   // if it will interpret ANSI color escape codes in a reasonable way. Thus, the
276   // strategy here is just to query the baseline colors capability and if it
277   // supports colors at all to assume it will translate the escape codes into
278   // whatever range of colors it does support. We can add more detailed tests
279   // here if users report them as necessary.
280   //
281   // The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
282   // the terminfo says that no colors are supported.
283   bool HasColors = tigetnum(const_cast<char *>("colors")) > 0;
284
285   // Now extract the structure allocated by setupterm and free its memory
286   // through a really silly dance.
287   struct term *termp = set_curterm((struct term *)0);
288   (void)del_curterm(termp); // Drop any errors here.
289
290   // Return true if we found a color capabilities for the current terminal.
291   if (HasColors)
292     return true;
293 #endif
294
295   // Otherwise, be conservative.
296   return false;
297 }
298
299 bool Process::FileDescriptorHasColors(int fd) {
300   // A file descriptor has colors if it is displayed and the terminal has
301   // colors.
302   return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
303 }
304
305 bool Process::StandardOutHasColors() {
306   return FileDescriptorHasColors(STDOUT_FILENO);
307 }
308
309 bool Process::StandardErrHasColors() {
310   return FileDescriptorHasColors(STDERR_FILENO);
311 }
312
313 bool Process::ColorNeedsFlush() {
314   // No, we use ANSI escape sequences.
315   return false;
316 }
317
318 #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
319
320 #define ALLCOLORS(FGBG,BOLD) {\
321     COLOR(FGBG, "0", BOLD),\
322     COLOR(FGBG, "1", BOLD),\
323     COLOR(FGBG, "2", BOLD),\
324     COLOR(FGBG, "3", BOLD),\
325     COLOR(FGBG, "4", BOLD),\
326     COLOR(FGBG, "5", BOLD),\
327     COLOR(FGBG, "6", BOLD),\
328     COLOR(FGBG, "7", BOLD)\
329   }
330
331 static const char colorcodes[2][2][8][10] = {
332  { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
333  { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
334 };
335
336 const char *Process::OutputColor(char code, bool bold, bool bg) {
337   return colorcodes[bg?1:0][bold?1:0][code&7];
338 }
339
340 const char *Process::OutputBold(bool bg) {
341   return "\033[1m";
342 }
343
344 const char *Process::OutputReverse() {
345   return "\033[7m";
346 }
347
348 const char *Process::ResetColor() {
349   return "\033[0m";
350 }
351
352 #if !defined(HAVE_ARC4RANDOM)
353 static unsigned GetRandomNumberSeed() {
354   // Attempt to get the initial seed from /dev/urandom, if possible.
355   if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) {
356     unsigned seed;
357     int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource);
358     ::fclose(RandomSource);
359
360     // Return the seed if the read was successful.
361     if (count == 1)
362       return seed;
363   }
364
365   // Otherwise, swizzle the current time and the process ID to form a reasonable
366   // seed.
367   TimeValue Now = TimeValue::now();
368   return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
369 }
370 #endif
371
372 unsigned llvm::sys::Process::GetRandomNumber() {
373 #if defined(HAVE_ARC4RANDOM)
374   return arc4random();
375 #else
376   static int x = (::srand(GetRandomNumberSeed()), 0);
377   (void)x;
378   return ::rand();
379 #endif
380 }