| #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); |
| } |
| } |