blob: 1bb3e2244c6389993e87d6791d29021becbc96dd [file] [log] [blame]
Reid Spencer33b9d772004-09-11 04:56:56 +00001//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
Michael J. Spencer447762d2010-11-29 18:16:10 +00002//
Reid Spencer33b9d772004-09-11 04:56:56 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Michael J. Spencer447762d2010-11-29 18:16:10 +00007//
Reid Spencer33b9d772004-09-11 04:56:56 +00008//===----------------------------------------------------------------------===//
9//
10// This file provides the generic Unix implementation of the Process class.
11//
12//===----------------------------------------------------------------------===//
13
Reid Spencerac38f3a2004-12-20 00:59:28 +000014#include "Unix.h"
Daniel Dunbar5f1c9562012-05-08 20:38:00 +000015#include "llvm/ADT/Hashing.h"
Chandler Carruthcad7e5e2013-08-07 08:47:36 +000016#include "llvm/Support/Mutex.h"
17#include "llvm/Support/MutexGuard.h"
Daniel Dunbar5f1c9562012-05-08 20:38:00 +000018#include "llvm/Support/TimeValue.h"
Reid Spencerac38f3a2004-12-20 00:59:28 +000019#ifdef HAVE_SYS_TIME_H
20#include <sys/time.h>
21#endif
22#ifdef HAVE_SYS_RESOURCE_H
23#include <sys/resource.h>
24#endif
Eric Christopher22738d02012-08-06 20:52:18 +000025// DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for
26// <stdlib.h> instead. Unix.h includes this for us already.
27#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \
28 !defined(__OpenBSD__) && !defined(__Bitrig__)
Reid Spencerac38f3a2004-12-20 00:59:28 +000029#include <malloc.h>
30#endif
Chris Lattner698fa762005-11-14 07:00:29 +000031#ifdef HAVE_MALLOC_MALLOC_H
32#include <malloc/malloc.h>
33#endif
Douglas Gregor15436612009-05-11 18:05:52 +000034#ifdef HAVE_SYS_IOCTL_H
35# include <sys/ioctl.h>
36#endif
Douglas Gregorb81294d2009-05-18 17:21:34 +000037#ifdef HAVE_TERMIOS_H
38# include <termios.h>
39#endif
Reid Spencer33b9d772004-09-11 04:56:56 +000040
Chandler Carruthf11f1e42013-08-12 09:49:17 +000041// Pull in the headers we found to go with the terminfo reading library (tinfo,
42// curses, whatever it may be). We have to pull in the 'curses.h' header as the
43// SysV spec only provides certain values and defines from that header even
44// though we work hard to not link against all of the curses implementation
45// when avoidable.
46#ifdef HAVE_TERMINFO
Chandler Carruthcad7e5e2013-08-07 08:47:36 +000047# if defined(HAVE_CURSES_H)
48# include <curses.h>
49# elif defined(HAVE_NCURSES_H)
50# include <ncurses.h>
51# elif defined(HAVE_NCURSESW_H)
52# include <ncursesw.h>
53# elif defined(HAVE_NCURSES_CURSES_H)
54# include <ncurses/curses.h>
55# elif defined(HAVE_NCURSESW_CURSES_H)
56# include <ncursesw/curses.h>
Chandler Carruthcad7e5e2013-08-07 08:47:36 +000057# endif
Chandler Carruthf11f1e42013-08-12 09:49:17 +000058# if defined(HAVE_TERM_H)
59# include <term.h>
60# endif
Chandler Carruthcad7e5e2013-08-07 08:47:36 +000061#endif
62
Reid Spencer33b9d772004-09-11 04:56:56 +000063//===----------------------------------------------------------------------===//
64//=== WARNING: Implementation here must contain only generic UNIX code that
65//=== is guaranteed to work on *all* UNIX variants.
66//===----------------------------------------------------------------------===//
67
Chris Lattner2f107cf2006-09-14 06:01:41 +000068using namespace llvm;
Reid Spencer33b9d772004-09-11 04:56:56 +000069using namespace sys;
70
Chandler Carruth97683aa2012-12-31 11:17:50 +000071
72process::id_type self_process::get_id() {
73 return getpid();
74}
75
Chandler Carruthef7f9682013-01-04 23:19:55 +000076static std::pair<TimeValue, TimeValue> getRUsageTimes() {
77#if defined(HAVE_GETRUSAGE)
78 struct rusage RU;
79 ::getrusage(RUSAGE_SELF, &RU);
80 return std::make_pair(
81 TimeValue(
82 static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
83 static_cast<TimeValue::NanoSecondsType>(
84 RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
85 TimeValue(
86 static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
87 static_cast<TimeValue::NanoSecondsType>(
88 RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
89#else
90#warning Cannot get usage times on this platform
91 return std::make_pair(TimeValue(), TimeValue());
92#endif
93}
94
95TimeValue self_process::get_user_time() const {
Chandler Carruthb5429f42013-01-05 00:42:50 +000096#if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0
Chandler Carruthef7f9682013-01-04 23:19:55 +000097 // Try to get a high resolution CPU timer.
98 struct timespec TS;
99 if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0)
100 return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec),
101 static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec));
102#endif
103
104 // Otherwise fall back to rusage based timing.
105 return getRUsageTimes().first;
106}
107
108TimeValue self_process::get_system_time() const {
109 // We can only collect system time by inspecting the results of getrusage.
110 return getRUsageTimes().second;
111}
112
Chandler Carruth15dcad92012-12-31 23:23:35 +0000113static unsigned getPageSize() {
Jay Foadc1fca9fb2009-05-23 17:57:59 +0000114#if defined(__CYGWIN__)
115 // On Cygwin, getpagesize() returns 64k but the page size for the purposes of
116 // memory protection and mmap() is 4k.
117 // See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492
Owen Andersona83e8682009-08-19 21:48:34 +0000118 const int page_size = 0x1000;
Jay Foadc1fca9fb2009-05-23 17:57:59 +0000119#elif defined(HAVE_GETPAGESIZE)
Owen Andersona83e8682009-08-19 21:48:34 +0000120 const int page_size = ::getpagesize();
Reid Spencerac38f3a2004-12-20 00:59:28 +0000121#elif defined(HAVE_SYSCONF)
Owen Andersona83e8682009-08-19 21:48:34 +0000122 long page_size = ::sysconf(_SC_PAGE_SIZE);
Reid Spencerac38f3a2004-12-20 00:59:28 +0000123#else
124#warning Cannot get the page size on this machine
125#endif
Reid Spencer33b9d772004-09-11 04:56:56 +0000126 return static_cast<unsigned>(page_size);
127}
128
Chandler Carruth15dcad92012-12-31 23:23:35 +0000129// This constructor guaranteed to be run exactly once on a single thread, and
130// sets up various process invariants that can be queried cheaply from then on.
131self_process::self_process() : PageSize(getPageSize()) {
132}
133
134
Chris Lattner698fa762005-11-14 07:00:29 +0000135size_t Process::GetMallocUsage() {
Reid Spencer1cf74ce2004-12-20 16:06:44 +0000136#if defined(HAVE_MALLINFO)
Reid Spencerac38f3a2004-12-20 00:59:28 +0000137 struct mallinfo mi;
138 mi = ::mallinfo();
139 return mi.uordblks;
Chris Lattner16cbc6a2005-11-14 07:27:56 +0000140#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
141 malloc_statistics_t Stats;
142 malloc_zone_statistics(malloc_default_zone(), &Stats);
143 return Stats.size_in_use; // darwin
Reid Spencer1cf74ce2004-12-20 16:06:44 +0000144#elif defined(HAVE_SBRK)
Reid Spencerac38f3a2004-12-20 00:59:28 +0000145 // Note this is only an approximation and more closely resembles
146 // the value returned by mallinfo in the arena field.
Chris Lattner698fa762005-11-14 07:00:29 +0000147 static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
148 char *EndOfMemory = (char*)sbrk(0);
149 if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
150 return EndOfMemory - StartOfMemory;
Reid Spencerac38f3a2004-12-20 00:59:28 +0000151 else
152 return 0;
153#else
154#warning Cannot get malloc info on this platform
155 return 0;
156#endif
157}
158
Chandler Carruthef7f9682013-01-04 23:19:55 +0000159void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
160 TimeValue &sys_time) {
Reid Spencerac38f3a2004-12-20 00:59:28 +0000161 elapsed = TimeValue::now();
Chandler Carruthef7f9682013-01-04 23:19:55 +0000162 llvm::tie(user_time, sys_time) = getRUsageTimes();
Reid Spencerac38f3a2004-12-20 00:59:28 +0000163}
164
Chris Lattner2f107cf2006-09-14 06:01:41 +0000165int Process::GetCurrentUserId() {
Reid Spencer2d45e252005-04-21 16:12:57 +0000166 return getuid();
167}
168
Chris Lattner2f107cf2006-09-14 06:01:41 +0000169int Process::GetCurrentGroupId() {
Reid Spencer2d45e252005-04-21 16:12:57 +0000170 return getgid();
171}
172
Sylvestre Ledru14ada942012-04-11 15:35:36 +0000173#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
Nate Begeman48405152008-04-12 00:47:46 +0000174#include <mach/mach.h>
175#endif
176
Reid Spencercf15b872004-12-27 06:17:27 +0000177// Some LLVM programs such as bugpoint produce core files as a normal part of
178// their operation. To prevent the disk from filling up, this function
179// does what's necessary to prevent their generation.
180void Process::PreventCoreFiles() {
181#if HAVE_SETRLIMIT
182 struct rlimit rlim;
183 rlim.rlim_cur = rlim.rlim_max = 0;
Chris Lattnerf64397b2006-05-14 18:53:09 +0000184 setrlimit(RLIMIT_CORE, &rlim);
Reid Spencercf15b872004-12-27 06:17:27 +0000185#endif
Chris Lattner2f107cf2006-09-14 06:01:41 +0000186
Sylvestre Ledru14ada942012-04-11 15:35:36 +0000187#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
Nate Begeman48405152008-04-12 00:47:46 +0000188 // Disable crash reporting on Mac OS X 10.0-10.4
189
190 // get information about the original set of exception ports for the task
191 mach_msg_type_number_t Count = 0;
192 exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
193 exception_port_t OriginalPorts[EXC_TYPES_COUNT];
194 exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
195 thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
Michael J. Spencer447762d2010-11-29 18:16:10 +0000196 kern_return_t err =
Nate Begeman48405152008-04-12 00:47:46 +0000197 task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
198 &Count, OriginalPorts, OriginalBehaviors,
199 OriginalFlavors);
200 if (err == KERN_SUCCESS) {
201 // replace each with MACH_PORT_NULL.
202 for (unsigned i = 0; i != Count; ++i)
Michael J. Spencer447762d2010-11-29 18:16:10 +0000203 task_set_exception_ports(mach_task_self(), OriginalMasks[i],
Nate Begeman48405152008-04-12 00:47:46 +0000204 MACH_PORT_NULL, OriginalBehaviors[i],
205 OriginalFlavors[i]);
206 }
207
208 // Disable crash reporting on Mac OS X 10.5
Nate Begemanf8be3832008-03-31 22:19:25 +0000209 signal(SIGABRT, _exit);
210 signal(SIGILL, _exit);
211 signal(SIGFPE, _exit);
212 signal(SIGSEGV, _exit);
213 signal(SIGBUS, _exit);
Chris Lattner2f107cf2006-09-14 06:01:41 +0000214#endif
Reid Spencercf15b872004-12-27 06:17:27 +0000215}
Reid Spencerac38f3a2004-12-20 00:59:28 +0000216
Reid Spencer6f802ba2005-01-01 22:29:26 +0000217bool Process::StandardInIsUserInput() {
Dan Gohmane5929232009-09-11 20:46:33 +0000218 return FileDescriptorIsDisplayed(STDIN_FILENO);
Reid Spencer6f802ba2005-01-01 22:29:26 +0000219}
220
221bool Process::StandardOutIsDisplayed() {
Dan Gohmane5929232009-09-11 20:46:33 +0000222 return FileDescriptorIsDisplayed(STDOUT_FILENO);
Reid Spencer6f802ba2005-01-01 22:29:26 +0000223}
224
225bool Process::StandardErrIsDisplayed() {
Dan Gohmane5929232009-09-11 20:46:33 +0000226 return FileDescriptorIsDisplayed(STDERR_FILENO);
227}
228
229bool Process::FileDescriptorIsDisplayed(int fd) {
Reid Spencer6f802ba2005-01-01 22:29:26 +0000230#if HAVE_ISATTY
Dan Gohmane5929232009-09-11 20:46:33 +0000231 return isatty(fd);
Duncan Sands44d423a2009-09-06 10:53:22 +0000232#else
Reid Spencer6f802ba2005-01-01 22:29:26 +0000233 // If we don't have isatty, just return false.
234 return false;
Duncan Sands44d423a2009-09-06 10:53:22 +0000235#endif
Reid Spencer6f802ba2005-01-01 22:29:26 +0000236}
Douglas Gregor15436612009-05-11 18:05:52 +0000237
238static unsigned getColumns(int FileID) {
239 // If COLUMNS is defined in the environment, wrap to that many columns.
240 if (const char *ColumnsStr = std::getenv("COLUMNS")) {
241 int Columns = std::atoi(ColumnsStr);
242 if (Columns > 0)
243 return Columns;
244 }
245
246 unsigned Columns = 0;
247
Douglas Gregorb81294d2009-05-18 17:21:34 +0000248#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
Douglas Gregor15436612009-05-11 18:05:52 +0000249 // Try to determine the width of the terminal.
250 struct winsize ws;
251 if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
252 Columns = ws.ws_col;
253#endif
254
255 return Columns;
256}
257
258unsigned Process::StandardOutColumns() {
259 if (!StandardOutIsDisplayed())
260 return 0;
261
262 return getColumns(1);
263}
264
265unsigned Process::StandardErrColumns() {
266 if (!StandardErrIsDisplayed())
267 return 0;
268
269 return getColumns(2);
270}
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000271
Chandler Carruthcad7e5e2013-08-07 08:47:36 +0000272static bool terminalHasColors(int fd) {
Chandler Carruthf11f1e42013-08-12 09:49:17 +0000273#ifdef HAVE_TERMINFO
274 // First, acquire a global lock because these C routines are thread hostile.
Chandler Carruthcad7e5e2013-08-07 08:47:36 +0000275 static sys::Mutex M;
276 MutexGuard G(M);
277
278 int errret = 0;
279 if (setupterm((char *)0, fd, &errret) != OK)
280 // Regardless of why, if we can't get terminfo, we shouldn't try to print
281 // colors.
282 return false;
283
Chandler Carruthf11f1e42013-08-12 09:49:17 +0000284 // Test whether the terminal as set up supports color output. How to do this
285 // isn't entirely obvious. We can use the curses routine 'has_colors' but it
286 // would be nice to avoid a dependency on curses proper when we can make do
287 // with a minimal terminfo parsing library. Also, we don't really care whether
288 // the terminal supports the curses-specific color changing routines, merely
289 // if it will interpret ANSI color escape codes in a reasonable way. Thus, the
290 // strategy here is just to query the baseline colors capability and if it
291 // supports colors at all to assume it will translate the escape codes into
292 // whatever range of colors it does support. We can add more detailed tests
293 // here if users report them as necessary.
294 //
295 // The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
296 // the terminfo says that no colors are supported.
297 if (tigetnum("colors") > 0)
Chandler Carruthcad7e5e2013-08-07 08:47:36 +0000298 return true;
299#endif
300
301 // Otherwise, be conservative.
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000302 return false;
303}
304
Daniel Dunbar712de822012-07-20 18:29:38 +0000305bool Process::FileDescriptorHasColors(int fd) {
306 // A file descriptor has colors if it is displayed and the terminal has
307 // colors.
Chandler Carruthcad7e5e2013-08-07 08:47:36 +0000308 return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
Daniel Dunbar712de822012-07-20 18:29:38 +0000309}
310
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000311bool Process::StandardOutHasColors() {
Daniel Dunbar712de822012-07-20 18:29:38 +0000312 return FileDescriptorHasColors(STDOUT_FILENO);
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000313}
314
315bool Process::StandardErrHasColors() {
Daniel Dunbar712de822012-07-20 18:29:38 +0000316 return FileDescriptorHasColors(STDERR_FILENO);
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000317}
318
319bool Process::ColorNeedsFlush() {
320 // No, we use ANSI escape sequences.
321 return false;
322}
323
324#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
325
326#define ALLCOLORS(FGBG,BOLD) {\
327 COLOR(FGBG, "0", BOLD),\
328 COLOR(FGBG, "1", BOLD),\
329 COLOR(FGBG, "2", BOLD),\
330 COLOR(FGBG, "3", BOLD),\
331 COLOR(FGBG, "4", BOLD),\
332 COLOR(FGBG, "5", BOLD),\
333 COLOR(FGBG, "6", BOLD),\
334 COLOR(FGBG, "7", BOLD)\
335 }
336
Nuno Lopes129819d2009-12-23 17:48:10 +0000337static const char colorcodes[2][2][8][10] = {
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000338 { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
339 { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
340};
341
342const char *Process::OutputColor(char code, bool bold, bool bg) {
343 return colorcodes[bg?1:0][bold?1:0][code&7];
344}
345
346const char *Process::OutputBold(bool bg) {
347 return "\033[1m";
348}
349
Benjamin Kramer13d16f32012-04-16 08:56:50 +0000350const char *Process::OutputReverse() {
351 return "\033[7m";
352}
353
Torok Edwin9b5a47f2009-06-04 07:09:50 +0000354const char *Process::ResetColor() {
355 return "\033[0m";
356}
NAKAMURA Takumi54acb282012-05-06 08:24:18 +0000357
NAKAMURA Takumi7bec7412012-05-06 08:24:24 +0000358#if !defined(HAVE_ARC4RANDOM)
359static unsigned GetRandomNumberSeed() {
Daniel Dunbar5f1c9562012-05-08 20:38:00 +0000360 // Attempt to get the initial seed from /dev/urandom, if possible.
361 if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) {
362 unsigned seed;
363 int count = ::fread((void *)&seed, sizeof(seed), 1, RandomSource);
NAKAMURA Takumi7bec7412012-05-06 08:24:24 +0000364 ::fclose(RandomSource);
Daniel Dunbar5f1c9562012-05-08 20:38:00 +0000365
366 // Return the seed if the read was successful.
367 if (count == 1)
368 return seed;
NAKAMURA Takumi7bec7412012-05-06 08:24:24 +0000369 }
Daniel Dunbar5f1c9562012-05-08 20:38:00 +0000370
371 // Otherwise, swizzle the current time and the process ID to form a reasonable
372 // seed.
Chandler Carruth5473dfb2012-12-31 11:45:20 +0000373 TimeValue Now = TimeValue::now();
Daniel Dunbar5f1c9562012-05-08 20:38:00 +0000374 return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
NAKAMURA Takumi7bec7412012-05-06 08:24:24 +0000375}
376#endif
377
NAKAMURA Takumi54acb282012-05-06 08:24:18 +0000378unsigned llvm::sys::Process::GetRandomNumber() {
379#if defined(HAVE_ARC4RANDOM)
380 return arc4random();
381#else
NAKAMURA Takumi7bec7412012-05-06 08:24:24 +0000382 static int x = (::srand(GetRandomNumberSeed()), 0);
383 (void)x;
NAKAMURA Takumi54acb282012-05-06 08:24:18 +0000384 return ::rand();
385#endif
386}