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
|
/* -----------------------------------------------------------------------------
*
* (c) The GHC Team, 2008-2009
*
* Support for fast binary event logging.
*
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
#include "Rts.h"
#include "RtsUtils.h"
#include "rts/EventLogWriter.h"
#include <string.h>
#include <stdio.h>
#include <fs_rts.h>
#if defined(HAVE_SYS_TYPES_H)
#include <sys/types.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
// PID of the process that writes to event_log_filename (#4512)
static pid_t event_log_pid = -1;
// File for logging events
static FILE *event_log_file = NULL;
static void initEventLogFileWriter(void);
static bool writeEventLogFile(void *eventlog, size_t eventlog_size);
static void flushEventLogFile(void);
static void stopEventLogFileWriter(void);
static void
initEventLogFileWriter(void)
{
char *prog, *event_log_filename;
prog = stgMallocBytes(strlen(prog_name) + 1, "initEventLogFileWriter");
strcpy(prog, prog_name);
#if defined(mingw32_HOST_OS)
// on Windows, drop the .exe suffix if there is one
{
char *suff;
suff = strrchr(prog,'.');
if (suff != NULL && !strcmp(suff,".exe")) {
*suff = '\0';
}
}
#endif
event_log_filename = stgMallocBytes(strlen(prog)
+ 10 /* .%d */
+ 10 /* .eventlog */,
"initEventLogFileWriter");
if (event_log_pid == -1) { // #4512
// Single process
sprintf(event_log_filename, "%s.eventlog", prog);
event_log_pid = getpid();
} else {
// Forked process, eventlog already started by the parent
// before fork
event_log_pid = getpid();
// We don't have a FMT* symbol for pid_t, so we go via Word64
// to be sure of not losing range. It would be nicer to have a
// FMT* symbol or similar, though.
sprintf(event_log_filename, "%s.%" FMT_Word64 ".eventlog",
prog, (StgWord64)event_log_pid);
}
stgFree(prog);
/* Open event log file for writing. */
if ((event_log_file = __rts_fopen(event_log_filename, "wb")) == NULL) {
sysErrorBelch(
"initEventLogFileWriter: can't open %s", event_log_filename);
stg_exit(EXIT_FAILURE);
}
stgFree(event_log_filename);
}
static bool
writeEventLogFile(void *eventlog, size_t eventlog_size)
{
unsigned char *begin = eventlog;
size_t remain = eventlog_size;
while (remain > 0) {
size_t written = fwrite(begin, 1, remain, event_log_file);
if (written == 0) {
return false;
}
remain -= written;
begin += written;
}
return true;
}
static void
flushEventLogFile(void)
{
if (event_log_file != NULL) {
fflush(event_log_file);
}
}
static void
stopEventLogFileWriter(void)
{
if (event_log_file != NULL) {
fclose(event_log_file);
}
}
const EventLogWriter FileEventLogWriter = {
.initEventLogWriter = initEventLogFileWriter,
.writeEventLog = writeEventLogFile,
.flushEventLog = flushEventLogFile,
.stopEventLogWriter = stopEventLogFileWriter
};
|