From 13931e5186fdb5a9b808abc09af5aa512cfdc7fa Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Jan 2025 10:24:06 +0000 Subject: [PATCH 1/2] cmake: detect realpath Change the realpath definition to have a CLAR_ prefix - `CLAR_HAS_REALPATH` - and check in the CMake run for it. --- CMakeLists.txt | 7 +++++++ clar/sandbox.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a680d0e..125db05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,16 @@ +include(CheckFunctionExists) + cmake_minimum_required(VERSION 3.16..3.29) project(clar LANGUAGES C) option(BUILD_EXAMPLE "Build the example." ON) +check_function_exists(realpath CLAR_HAS_REALPATH) +if(CLAR_HAS_REALPATH) + add_compile_definitions(-DCLAR_HAS_REALPATH) +endif() + add_library(clar INTERFACE) target_sources(clar INTERFACE clar.c diff --git a/clar/sandbox.h b/clar/sandbox.h index 7c19940..3f45d67 100644 --- a/clar/sandbox.h +++ b/clar/sandbox.h @@ -104,7 +104,7 @@ static int canonicalize_tmp_path(char *buffer) *p = '/'; return 0; -#elif defined(__APPLE__) || defined(HAS_REALPATH) +#elif defined(CLAR_HAS_REALPATH) char tmp[CLAR_MAX_PATH]; if (realpath(buffer, tmp) == NULL) From 18c6e268cb0862b4125c79e970ef4e6d17d88c78 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 23 Jan 2025 10:26:14 +0000 Subject: [PATCH 2/2] Using test names as sandbox dirs is now optional Given that test names can be long _and_ some platforms insist upon a short maximum path length (eg, Windows), we may not want to indiscriminately use path names as the sandbox directory name. However, this has high utility in some situations, so allow it as an opt-in. By default, we'll just use an 8 hexadigit "random" string. (We'll use the rand(3) mechanism, which is not be particularly random, but since the sandbox directories are sequestered in a unique tempdir, a clar process need only attempt to avoid collisions between itself, not with other processes.) --- clar/sandbox.h | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/clar/sandbox.h b/clar/sandbox.h index 3f45d67..ff43159 100644 --- a/clar/sandbox.h +++ b/clar/sandbox.h @@ -187,6 +187,12 @@ static void clar_tempdir_init(void) if (chdir(_clar_tempdir) != 0) clar_abort("Failed to change into tempdir '%s': %s.\n", _clar_tempdir, strerror(errno)); + +#if !defined(CLAR_SANDBOX_TEST_NAMES) && defined(_WIN32) + srand(clock() ^ (unsigned int)time(NULL) ^ GetCurrentProcessId() ^ GetCurrentThreadId()); +#elif !defined(CLAR_SANDBOX_TEST_NAMES) + srand(clock() ^ time(NULL) ^ (getpid() << 16)); +#endif } static void append(char *dst, const char *src) @@ -208,9 +214,20 @@ static void append(char *dst, const char *src) static int clar_sandbox_create(const char *suite_name, const char *test_name) { +#ifndef CLAR_SANDBOX_TEST_NAMES + char alpha[] = "0123456789abcdef"; + int num = rand(); +#endif + cl_assert(_clar_sandbox[0] == '\0'); - cl_assert(strlen(_clar_tempdir) + strlen(suite_name) + strlen(test_name) + 2 < CLAR_MAX_PATH); + /* + * We may want to use test names as sandbox directory names for + * readability, _however_ on platforms with restrictions for short + * file / folder names (eg, Windows), this may be too long. + */ +#ifdef CLAR_SANDBOX_TEST_NAMES + cl_assert(strlen(_clar_tempdir) + strlen(suite_name) + strlen(test_name) + 3 < CLAR_MAX_PATH); strcpy(_clar_sandbox, _clar_tempdir); _clar_sandbox[_clar_tempdir_len] = '/'; @@ -219,6 +236,26 @@ static int clar_sandbox_create(const char *suite_name, const char *test_name) append(_clar_sandbox, suite_name); append(_clar_sandbox, "__"); append(_clar_sandbox, test_name); +#else + ((void)suite_name); + ((void)test_name); + ((void)append); + + cl_assert(strlen(_clar_tempdir) + 9 < CLAR_MAX_PATH); + + strcpy(_clar_sandbox, _clar_tempdir); + _clar_sandbox[_clar_tempdir_len] = '/'; + + _clar_sandbox[_clar_tempdir_len + 1] = alpha[(num & 0xf0000000) >> 28]; + _clar_sandbox[_clar_tempdir_len + 2] = alpha[(num & 0x0f000000) >> 24]; + _clar_sandbox[_clar_tempdir_len + 3] = alpha[(num & 0x00f00000) >> 20]; + _clar_sandbox[_clar_tempdir_len + 4] = alpha[(num & 0x000f0000) >> 16]; + _clar_sandbox[_clar_tempdir_len + 5] = alpha[(num & 0x0000f000) >> 12]; + _clar_sandbox[_clar_tempdir_len + 6] = alpha[(num & 0x00000f00) >> 8]; + _clar_sandbox[_clar_tempdir_len + 7] = alpha[(num & 0x000000f0) >> 4]; + _clar_sandbox[_clar_tempdir_len + 8] = alpha[(num & 0x0000000f) >> 0]; + _clar_sandbox[_clar_tempdir_len + 9] = '\0'; +#endif if (mkdir(_clar_sandbox, 0700) != 0) return -1;