X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..dd5fb164cf5b32c462296bc65e289e100f74b59a:/OSX/regressions/test/testmore.c diff --git a/OSX/regressions/test/testmore.c b/OSX/regressions/test/testmore.c index 4d443485..bb36f8df 100644 --- a/OSX/regressions/test/testmore.c +++ b/OSX/regressions/test/testmore.c @@ -24,6 +24,8 @@ */ #include +#include +#include #include #include #include @@ -35,6 +37,7 @@ #include "testmore.h" #include "testenv.h" +pthread_mutex_t test_mutex; // protects the test number variables static int test_fails = 0; static int test_todo_pass = 0; static int test_todo = 0; @@ -59,9 +62,9 @@ static void fprint_string(FILE *file, CFStringRef string) { } } -static void cffprint(FILE *file, CFStringRef fmt, ...) CF_FORMAT_FUNCTION(2,0); +static void cffprint(FILE *file, CFStringRef fmt, ...) CF_FORMAT_FUNCTION(2,3); -static void cffprint_v(FILE *file, CFStringRef fmt, va_list args); +static void cffprint_v(FILE *file, CFStringRef fmt, va_list args) CF_FORMAT_FUNCTION(2,0); static void cffprint_c_v(FILE *file, const char *fmt, va_list args); static void cffprint_v(FILE *file, CFStringRef fmt, va_list args) { @@ -70,12 +73,18 @@ static void cffprint_v(FILE *file, CFStringRef fmt, va_list args) { CFRelease(line); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" + static void cffprint_c_v(FILE *file, const char *fmt, va_list args) { CFStringRef cffmt = CFStringCreateWithCString(kCFAllocatorDefault, fmt, kCFStringEncodingUTF8); cffprint_v(file, cffmt, args); CFRelease(cffmt); } +#pragma clang diagnostic pop + + static void cffprint(FILE *file, CFStringRef fmt, ...) { va_list args; va_start(args, fmt); @@ -102,9 +111,14 @@ void test_bail_out(const char *reason, const char *file, unsigned line) void test_plan_skip_all(const char *reason) { - if (test_num < test_cases) + // Not super thread-safe. Don't test_plan_skip_all from multiple threads simultaneously. + pthread_mutex_lock(&test_mutex); + int skipN = test_cases - test_num; + pthread_mutex_unlock(&test_mutex); + + if (skipN > 0) { - test_skip(reason, test_cases - test_num, 0); + test_skip(reason, skipN, 0); } } @@ -125,6 +139,8 @@ static int test_plan_pass(void) { return 0; } +static int test_plan_fail(CFStringRef reason, ...) CF_FORMAT_FUNCTION(1, 2); + static int test_plan_fail(CFStringRef reason, ...) { const char *name = test_plan_name(); va_list ap; @@ -144,6 +160,7 @@ int test_plan_ok(void) { fflush(stderr); const char *name = test_plan_name(); + pthread_mutex_lock(&test_mutex); if (!test_num) { if (test_cases) @@ -170,11 +187,13 @@ int test_plan_ok(void) { fprintf(stdout, "%s failed %d tests of %d.\n", name, test_fails, test_num); status = 1; } + pthread_mutex_unlock(&test_mutex); fflush(stdout); return status; } +// You should hold the test_mutex when you call this. static void test_plan_reset(void) { test_fails = 0; test_todo_pass = 0; @@ -186,6 +205,7 @@ static void test_plan_reset(void) { } void test_plan_final(int *failed, int *todo_pass, int *todo, int *actual, int *planned, const char **file, int *line) { + pthread_mutex_lock(&test_mutex); if (failed) *failed = test_fails; if (todo_pass) @@ -202,6 +222,7 @@ void test_plan_final(int *failed, int *todo_pass, int *todo, int *actual, int *p *line = test_plan_line; test_plan_reset(); + pthread_mutex_unlock(&test_mutex); } void test_plan_tests(int count, const char *file, unsigned line) { @@ -226,6 +247,13 @@ void test_plan_tests(int count, const char *file, unsigned line) { test_plan_line=line; test_cases = count; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if(pthread_mutex_init(&test_mutex, NULL) != 0) { + fprintf(stdout, "Failed to initialize mutex: %d\n", errno); + } + }); } } @@ -261,7 +289,7 @@ test_diag(const char *directive, const char *reason, } int -test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive, +test_ok(int passed, __attribute((cf_consumed)) CFStringRef CF_CONSUMED description, const char *directive, const char *reason, const char *file, unsigned line, const char *fmt, ...) { @@ -298,6 +326,7 @@ test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const ch //fflush(stdout); } + pthread_mutex_lock(&test_mutex); ++test_num; if (passed) { if (is_todo) { @@ -342,6 +371,7 @@ test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const ch reason ? reason : ""); fflush(stdout); } + pthread_mutex_unlock(&test_mutex); } if (description) @@ -350,28 +380,43 @@ test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const ch return passed; } + // TODO: Move this to testsec.h so that testmore and testenv can be shared +static void buf_kill(void* p) { + free(p); +} + const char * sec_errstr(int err) { -#if 1 - static int bufnum = 0; - static char buf[2][20]; - bufnum = bufnum ? 0 : 1; - sprintf(buf[bufnum], "0x%X", err); - return buf[bufnum]; -#else /* !1 */ - if (err >= errSecErrnoBase && err <= errSecErrnoLimit) - return strerror(err - 100000); - -#ifdef MAC_OS_X_VERSION_10_4 - /* AvailabilityMacros.h would only define this if we are on a - Tiger or later machine. */ - extern const char *cssmErrorString(long); - return cssmErrorString(err); -#else /* !defined(MAC_OS_X_VERSION_10_4) */ - extern const char *_ZN8Security15cssmErrorStringEl(long); - return _ZN8Security15cssmErrorStringEl(err); -#endif /* MAC_OS_X_VERSION_10_4 */ -#endif /* !1 */ + static pthread_key_t buffer0key; + static pthread_key_t buffer1key; + static pthread_key_t switchkey; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + pthread_key_create(&buffer0key, buf_kill); + pthread_key_create(&buffer1key, buf_kill); + pthread_key_create(&switchkey, buf_kill); + }); + + uint32_t * switchp = (uint32_t*) pthread_getspecific(switchkey); + if(switchp == NULL) { + switchp = (uint32_t*) malloc(sizeof(uint32_t)); + *switchp = 0; + pthread_setspecific(switchkey, switchp); + } + + char* buf = NULL; + + pthread_key_t current = (*switchp) ? buffer0key : buffer1key; + *switchp = !(*switchp); + + buf = pthread_getspecific(current); + if(buf == NULL) { + buf = (char*) malloc(20); + pthread_setspecific(current, buf); + } + + snprintf(buf, 20, "0x%X", err); + return buf; }