~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/System/Unix/Process.inc

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifdef HAVE_SYS_TIME_H
 
16
#include <sys/time.h>
 
17
#endif
 
18
#ifdef HAVE_SYS_RESOURCE_H
 
19
#include <sys/resource.h>
 
20
#endif
 
21
// DragonFly BSD has deprecated <malloc.h> for <stdlib.h> instead,
 
22
//  Unix.h includes this for us already.
 
23
#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__)
 
24
#include <malloc.h>
 
25
#endif
 
26
#ifdef HAVE_MALLOC_MALLOC_H
 
27
#include <malloc/malloc.h>
 
28
#endif
 
29
#ifdef HAVE_SYS_IOCTL_H
 
30
#  include <sys/ioctl.h>
 
31
#endif
 
32
#ifdef HAVE_TERMIOS_H
 
33
#  include <termios.h>
 
34
#endif
 
35
 
 
36
//===----------------------------------------------------------------------===//
 
37
//=== WARNING: Implementation here must contain only generic UNIX code that
 
38
//===          is guaranteed to work on *all* UNIX variants.
 
39
//===----------------------------------------------------------------------===//
 
40
 
 
41
using namespace llvm;
 
42
using namespace sys;
 
43
 
 
44
unsigned 
 
45
Process::GetPageSize() 
 
46
{
 
47
#if defined(__CYGWIN__)
 
48
  // On Cygwin, getpagesize() returns 64k but the page size for the purposes of
 
49
  // memory protection and mmap() is 4k.
 
50
  // See http://www.cygwin.com/ml/cygwin/2009-01/threads.html#00492
 
51
  const int page_size = 0x1000;
 
52
#elif defined(HAVE_GETPAGESIZE)
 
53
  const int page_size = ::getpagesize();
 
54
#elif defined(HAVE_SYSCONF)
 
55
  long page_size = ::sysconf(_SC_PAGE_SIZE);
 
56
#else
 
57
#warning Cannot get the page size on this machine
 
58
#endif
 
59
  return static_cast<unsigned>(page_size);
 
60
}
 
61
 
 
62
size_t Process::GetMallocUsage() {
 
63
#if defined(HAVE_MALLINFO)
 
64
  struct mallinfo mi;
 
65
  mi = ::mallinfo();
 
66
  return mi.uordblks;
 
67
#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
 
68
  malloc_statistics_t Stats;
 
69
  malloc_zone_statistics(malloc_default_zone(), &Stats);
 
70
  return Stats.size_in_use;   // darwin
 
71
#elif defined(HAVE_SBRK)
 
72
  // Note this is only an approximation and more closely resembles
 
73
  // the value returned by mallinfo in the arena field.
 
74
  static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
 
75
  char *EndOfMemory = (char*)sbrk(0);
 
76
  if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
 
77
    return EndOfMemory - StartOfMemory;
 
78
  else
 
79
    return 0;
 
80
#else
 
81
#warning Cannot get malloc info on this platform
 
82
  return 0;
 
83
#endif
 
84
}
 
85
 
 
86
size_t
 
87
Process::GetTotalMemoryUsage()
 
88
{
 
89
#if defined(HAVE_MALLINFO)
 
90
  struct mallinfo mi = ::mallinfo();
 
91
  return mi.uordblks + mi.hblkhd;
 
92
#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
 
93
  malloc_statistics_t Stats;
 
94
  malloc_zone_statistics(malloc_default_zone(), &Stats);
 
95
  return Stats.size_allocated;   // darwin
 
96
#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
 
97
  struct rusage usage;
 
98
  ::getrusage(RUSAGE_SELF, &usage);
 
99
  return usage.ru_maxrss;
 
100
#else
 
101
#warning Cannot get total memory size on this platform
 
102
  return 0;
 
103
#endif
 
104
}
 
105
 
 
106
void
 
107
Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time, 
 
108
                      TimeValue& sys_time)
 
109
{
 
110
  elapsed = TimeValue::now();
 
111
#if defined(HAVE_GETRUSAGE)
 
112
  struct rusage usage;
 
113
  ::getrusage(RUSAGE_SELF, &usage);
 
114
  user_time = TimeValue( 
 
115
    static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ), 
 
116
    static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec * 
 
117
      TimeValue::NANOSECONDS_PER_MICROSECOND ) );
 
118
  sys_time = TimeValue( 
 
119
    static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ), 
 
120
    static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec * 
 
121
      TimeValue::NANOSECONDS_PER_MICROSECOND ) );
 
122
#else
 
123
#warning Cannot get usage times on this platform
 
124
  user_time.seconds(0);
 
125
  user_time.microseconds(0);
 
126
  sys_time.seconds(0);
 
127
  sys_time.microseconds(0);
 
128
#endif
 
129
}
 
130
 
 
131
int Process::GetCurrentUserId() {
 
132
  return getuid();
 
133
}
 
134
 
 
135
int Process::GetCurrentGroupId() {
 
136
  return getgid();
 
137
}
 
138
 
 
139
#ifdef HAVE_MACH_MACH_H
 
140
#include <mach/mach.h>
 
141
#endif
 
142
 
 
143
// Some LLVM programs such as bugpoint produce core files as a normal part of
 
144
// their operation. To prevent the disk from filling up, this function
 
145
// does what's necessary to prevent their generation.
 
146
void Process::PreventCoreFiles() {
 
147
#if HAVE_SETRLIMIT
 
148
  struct rlimit rlim;
 
149
  rlim.rlim_cur = rlim.rlim_max = 0;
 
150
  setrlimit(RLIMIT_CORE, &rlim);
 
151
#endif
 
152
 
 
153
#ifdef HAVE_MACH_MACH_H
 
154
  // Disable crash reporting on Mac OS X 10.0-10.4
 
155
 
 
156
  // get information about the original set of exception ports for the task
 
157
  mach_msg_type_number_t Count = 0;
 
158
  exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
 
159
  exception_port_t OriginalPorts[EXC_TYPES_COUNT];
 
160
  exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
 
161
  thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
 
162
  kern_return_t err = 
 
163
    task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
 
164
                             &Count, OriginalPorts, OriginalBehaviors,
 
165
                             OriginalFlavors);
 
166
  if (err == KERN_SUCCESS) {
 
167
    // replace each with MACH_PORT_NULL.
 
168
    for (unsigned i = 0; i != Count; ++i)
 
169
      task_set_exception_ports(mach_task_self(), OriginalMasks[i], 
 
170
                               MACH_PORT_NULL, OriginalBehaviors[i],
 
171
                               OriginalFlavors[i]);
 
172
  }
 
173
 
 
174
  // Disable crash reporting on Mac OS X 10.5
 
175
  signal(SIGABRT, _exit);
 
176
  signal(SIGILL,  _exit);
 
177
  signal(SIGFPE,  _exit);
 
178
  signal(SIGSEGV, _exit);
 
179
  signal(SIGBUS,  _exit);
 
180
#endif
 
181
}
 
182
 
 
183
bool Process::StandardInIsUserInput() {
 
184
  return FileDescriptorIsDisplayed(STDIN_FILENO);
 
185
}
 
186
 
 
187
bool Process::StandardOutIsDisplayed() {
 
188
  return FileDescriptorIsDisplayed(STDOUT_FILENO);
 
189
}
 
190
 
 
191
bool Process::StandardErrIsDisplayed() {
 
192
  return FileDescriptorIsDisplayed(STDERR_FILENO);
 
193
}
 
194
 
 
195
bool Process::FileDescriptorIsDisplayed(int fd) {
 
196
#if HAVE_ISATTY
 
197
  return isatty(fd);
 
198
#else
 
199
  // If we don't have isatty, just return false.
 
200
  return false;
 
201
#endif
 
202
}
 
203
 
 
204
static unsigned getColumns(int FileID) {
 
205
  // If COLUMNS is defined in the environment, wrap to that many columns.
 
206
  if (const char *ColumnsStr = std::getenv("COLUMNS")) {
 
207
    int Columns = std::atoi(ColumnsStr);
 
208
    if (Columns > 0)
 
209
      return Columns;
 
210
  }
 
211
 
 
212
  unsigned Columns = 0;
 
213
 
 
214
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
 
215
  // Try to determine the width of the terminal.
 
216
  struct winsize ws;
 
217
  if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
 
218
    Columns = ws.ws_col;
 
219
#endif
 
220
 
 
221
  return Columns;
 
222
}
 
223
 
 
224
unsigned Process::StandardOutColumns() {
 
225
  if (!StandardOutIsDisplayed())
 
226
    return 0;
 
227
 
 
228
  return getColumns(1);
 
229
}
 
230
 
 
231
unsigned Process::StandardErrColumns() {
 
232
  if (!StandardErrIsDisplayed())
 
233
    return 0;
 
234
 
 
235
  return getColumns(2);
 
236
}
 
237
 
 
238
static bool terminalHasColors() {
 
239
  if (const char *term = std::getenv("TERM")) {
 
240
    // Most modern terminals support ANSI escape sequences for colors.
 
241
    // We could check terminfo, or have a list of known terms that support
 
242
    // colors, but that would be overkill.
 
243
    // The user can always ask for no colors by setting TERM to dumb, or
 
244
    // using a commandline flag.
 
245
    return strcmp(term, "dumb") != 0;
 
246
  }
 
247
  return false;
 
248
}
 
249
 
 
250
bool Process::StandardOutHasColors() {
 
251
  if (!StandardOutIsDisplayed())
 
252
    return false;
 
253
  return terminalHasColors();
 
254
}
 
255
 
 
256
bool Process::StandardErrHasColors() {
 
257
  if (!StandardErrIsDisplayed())
 
258
    return false;
 
259
  return terminalHasColors();
 
260
}
 
261
 
 
262
bool Process::ColorNeedsFlush() {
 
263
  // No, we use ANSI escape sequences.
 
264
  return false;
 
265
}
 
266
 
 
267
#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
 
268
 
 
269
#define ALLCOLORS(FGBG,BOLD) {\
 
270
    COLOR(FGBG, "0", BOLD),\
 
271
    COLOR(FGBG, "1", BOLD),\
 
272
    COLOR(FGBG, "2", BOLD),\
 
273
    COLOR(FGBG, "3", BOLD),\
 
274
    COLOR(FGBG, "4", BOLD),\
 
275
    COLOR(FGBG, "5", BOLD),\
 
276
    COLOR(FGBG, "6", BOLD),\
 
277
    COLOR(FGBG, "7", BOLD)\
 
278
  }
 
279
 
 
280
static const char colorcodes[2][2][8][10] = {
 
281
 { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
 
282
 { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
 
283
};
 
284
 
 
285
const char *Process::OutputColor(char code, bool bold, bool bg) {
 
286
  return colorcodes[bg?1:0][bold?1:0][code&7];
 
287
}
 
288
 
 
289
const char *Process::OutputBold(bool bg) {
 
290
  return "\033[1m";
 
291
}
 
292
 
 
293
const char *Process::ResetColor() {
 
294
  return "\033[0m";
 
295
}