From 6625ac077a47fa39e08c0cc7c55ad72b45cf12fd Mon Sep 17 00:00:00 2001 From: Aaron Dierking Date: Sat, 2 Feb 2019 15:24:13 -0800 Subject: [PATCH] dispatch: fix logging to a file on Windows Port the dispatch_debug test to Windows and fix a bug that it found related to logfile initialization. _dispatch_logv_init()'s Windows implementation uses _fdopen() and fprintf() to write the log header. However, this gives ownership of the file to stdio, so fclose() closes the descriptor and causes future writes to trigger CRT assertion failures. Avoid this by using snprintf() and _write() instead. --- src/init.c | 16 ++++++++++------ tests/dispatch_debug.c | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/init.c b/src/init.c index 11dabb9c7..e2131ca34 100644 --- a/src/init.c +++ b/src/init.c @@ -733,15 +733,19 @@ _dispatch_logv_init(void *context DISPATCH_UNUSED) dispatch_log_basetime = _dispatch_absolute_time(); #endif #if defined(_WIN32) - FILE *pLogFile = _fdopen(dispatch_logfile, "w"); - char szProgramName[MAX_PATH + 1] = {0}; GetModuleFileNameA(NULL, szProgramName, MAX_PATH); - fprintf(pLogFile, "=== log file opened for %s[%lu] at " - "%ld.%06u ===\n", szProgramName, GetCurrentProcessId(), - tv.tv_sec, (int)tv.tv_usec); - fclose(pLogFile); + char szMessage[512]; + int len = snprintf(szMessage, sizeof(szMessage), + "=== log file opened for %s[%lu] at %ld.%06u ===", + szProgramName, GetCurrentProcessId(), tv.tv_sec, + (int)tv.tv_usec); + if (len > 0) { + len = MIN(len, sizeof(szMessage) - 1); + _write(dispatch_logfile, szMessage, len); + _write(dispatch_logfile, "\n", 1); + } #else dprintf(dispatch_logfile, "=== log file opened for %s[%u] at " "%ld.%06u ===\n", getprogname() ?: "", getpid(), diff --git a/tests/dispatch_debug.c b/tests/dispatch_debug.c index 858c57241..df9900d65 100644 --- a/tests/dispatch_debug.c +++ b/tests/dispatch_debug.c @@ -31,7 +31,11 @@ int main(void) { +#if defined(_WIN32) + _putenv_s("LIBDISPATCH_LOG", "stderr"); +#else setenv("LIBDISPATCH_LOG", "stderr", 1); // rdar://problem/8493990 +#endif dispatch_test_start("Dispatch Debug"); dispatch_queue_t main_q = dispatch_get_main_queue();