/** * Open a temporary file. * * If the file could be unlinked upon creation, the name * of the file is not returned via 'name'. However, if the * file could not be unlinked, the name is returned, * expecting the caller to both delete the file and * free the 'name' field after the file is closed. */ FILE *open_tmp_file(char **name) { FILE *file = NULL; *name = NULL; #if !HAVE_MKSTEMP /* Windows does not like tmpfile(). This is likely because tmpfile() * call unlink() on the file before returning it, to make sure the * file is deleted when it is closed. The unlink() call also fails * on Windows if the file is still open. */ /* also note that mkstemp is apparently a C90 replacement for tmpfile */ /* perhaps all we need to do on Windows is set TMPDIR to whatever is stored in TEMP for tmpfile to work */ /* and finally, the "b" from "w+b" is ignored on OS X, not sure about WIN32 */ file = tmpfile(); if(file == NULL) { char *tmp = getenv("TEMP"); char *tmp_file = tempnam(tmp, "check_"); /* * Note, tempnam is not enough to get a unique name. Between * getting the name and opening the file, something else also * calling tempnam() could get the same name. It has been observed * on MinGW-w64 builds on Wine that this exact thing happens * if multiple instances of a unit tests are running concurrently. * To prevent two concurrent unit tests from getting the same file, * we append the pid to the file. The pid should be unique on the * system. */ char *uniq_tmp_file = ck_strdup_printf("%s.%d", tmp_file, getpid()); file = fopen(uniq_tmp_file, "w+b"); *name = uniq_tmp_file; free(tmp_file); } #else int fd = -1; const char *tmp_dir = getenv ("TEMP"); if (!tmp_dir) { tmp_dir = "."; } *name = ck_strdup_printf ("%s/check_XXXXXX", tmp_dir); if (-1 < (fd = mkstemp (*name))) { file = fdopen (fd, "w+b"); if (0 == unlink (*name) || NULL == file) { free (*name); *name = NULL; } } #endif return file; }
char *sr_stat_str (SRunner *sr) { char *str; TestStats *ts; ts = sr->stats; str = ck_strdup_printf ("%d%%: Checks: %d, Failures: %d, Errors: %d", percent_passed (ts), ts->n_checked, ts->n_failed, ts->n_errors); return str; }
char *tr_short_str (TestResult *tr) { const char *exact_msg; char *rstr; exact_msg = (tr->rtype == CK_ERROR) ? "(after this point) ": ""; rstr = ck_strdup_printf ("%s:%d: %s%s", tr->file, tr->line, exact_msg, tr->msg); return rstr; }