blob: f910ae565e228a782a47241c794b71f9f02bf88f [file] [log] [blame]
#include "barectf-init.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for getcwd
#include <sys/stat.h> // for mkdir and stat
#define MAX_PATH 256
#define MAX_TFOLDERS 20
struct barectf_platform_fs_ctx *platform_ctx = NULL;
/**
* handle (termination) signals
*/
#if defined(__WIN32__) || defined(WIN32) || defined(WIN64) || defined(__WIN64__)
#include <windows.h>
#include <direct.h> // for mkdir
BOOL WINAPI consoleHandler(DWORD signal) {
if (signal == CTRL_C_EVENT
|| signal == CTRL_CLOSE_EVENT
|| signal == CTRL_BREAK_EVENT
) {
barectf_platform_fs_fini(platform_ctx);
exit(0);
}
return TRUE;
}
#else
// POSIX OS
#include <signal.h>
void barectf_terminate(int signum) {
if (platform_ctx != NULL) {
barectf_platform_fs_fini (platform_ctx);
}
exit(0);
}
#endif
/**
* Initialize BareCTF
*/
struct barectf_default_ctx* barectf_papy_init(const char *metadataPath) {
const char *traceFolderEnvVar = "CTF_TRACE_FOLDER";
const char *traceBufSizeEnvVar = "CTF_TRACE_BUFSIZE";
const char *traceFolder = getenv(traceFolderEnvVar);
if (traceFolder == NULL) {
traceFolder = "ctftrace";
}
char traceFolderN[strlen(traceFolder) + 3];
unsigned char found = 0;
// find non-existing folder for trace
for (int i = 0; i < MAX_TFOLDERS; i++) {
struct stat statbuf;
sprintf(traceFolderN, "%s%02d", traceFolder, i);
statbuf.st_mode = 0;
stat(traceFolderN, &statbuf);
if (S_ISREG(statbuf.st_mode)) {
printf("%s is a regular file and not a folder. Consider deleting it.\n", traceFolderN);
exit(1);
}
else if (!S_ISDIR(statbuf.st_mode)) {
#if defined(__WIN32__) || defined(WIN32) || defined(WIN64) || defined(__WIN64__)
if (mkdir(traceFolderN) != 0) {
#else
if (mkdir(traceFolderN, 0755) != 0) {
#endif
fprintf(stderr,
"Trace folder \"%s\" does not exist and could not be created.\n"
"Set the environment variable \"%s\" to provide a custom folder\n",
traceFolderN, traceFolderEnvVar);
exit(1);
}
// empty folder found
found = 1;
break;
}
}
if (!found) {
fprintf(stderr, "cannot create a new folder for tracing, consider deleting existing trace folders\n");
exit(1);
}
char stream[strlen(traceFolderN) + 8];
strcpy(stream, traceFolderN);
strcat(stream, "/stream");
char cwd_buf[MAX_PATH];
getcwd(cwd_buf, MAX_PATH);
printf("writing trace stream to folder \"%s\"\n", traceFolderN);
printf("(in current working directory \"%s\")\n", cwd_buf);
int bufSize = 512;
const char *bufSizeStr = getenv(traceBufSizeEnvVar);
if (bufSizeStr != NULL) {
bufSize = atoi(bufSizeStr);
}
// copy metadata
char metadata[strlen(traceFolderN) + 10];
strcpy(metadata, traceFolderN);
strcat(metadata, "/metadata");
FILE *fmetadata = fopen(metadata, "r");
if (fmetadata == NULL) {
FILE *fs_metadata = fopen(metadataPath, "r");
if (fs_metadata != NULL) {
fmetadata = fopen(metadata, "w");
if (fmetadata != NULL) {
char ch;
while ((ch = fgetc(fs_metadata)) != EOF)
fputc(ch, fmetadata);
fclose(fs_metadata);
} else {
fprintf(stderr, "cannot open \"%s\" for writing\n", metadata);
}
} else {
fprintf(stderr,
"cannot find source meta data in \"%s\". Please copy it manually.\n",
metadataPath);
}
}
if (fmetadata != NULL) {
fclose(fmetadata);
}
/*
* Obtain a platform context.
*
* The platform is configured to write bufSize-byte packets to a data
* stream file within the "mytrace" directory.
*/
platform_ctx = barectf_platform_fs_init(bufSize, stream, 0, 0, 0);
// register termination action (assure that buffer gets written)
#if defined(__WIN32__) || defined(WIN32) || defined(WIN64) || defined(__WIN64__)
if (!SetConsoleCtrlHandler(consoleHandler, TRUE)) {
printf("\nERROR: Could not set control handler");
}
#else
// POSIX OS
struct sigaction action;
memset(&action, 0, sizeof(struct sigaction));
action.sa_handler = barectf_terminate;
sigaction(SIGINT, &action, NULL);
sigaction(SIGTERM, &action, NULL);
// remove SIGKILL, as not support by cygwin
// sigaction(SIGKILL, &action, NULL);
sigaction(SIGSEGV, &action, NULL);
#endif
// Obtain the barectf context from the platform context
return barectf_platform_fs_get_barectf_ctx(platform_ctx);
}
/**
* Terminate BareCTF
*/
void barectf_papy_fini() {
/* Finalize (free) the platform context */
if (platform_ctx != NULL) {
barectf_platform_fs_fini(platform_ctx);
}
}