Hier ist, wie ich es testen würde, nur um des Testens willen, da fizzer uns daran erinnert hat fclose()
zweimal ist unsicher.
Es ist möglich neu definieren fclose()
(oder eine andere Funktion der libc) in Ihrem Programm mit Ihrem eigenen Verhalten . Auf Unix-ähnlichen Systemen beschwert sich der Linker nicht - unter Windows habe ich es nie versucht, aber mit cygwin. Natürlich verhindert dies, dass Ihre anderen Tests den echten fclose()
Daher muss ein solcher Test in einer separaten ausführbaren Testdatei gespeichert werden.
Hier ein umfassendes Beispiel mit Minieinheit .
#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
/* from minunit.h : http://www.jera.com/techinfo/jtns/jtn002.html */
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { char *message = test(); tests_run++; \
if (message) return message; } while (0)
int tests_run = 0;
bool fclose_shall_fail_on_EINTR = false;
//--- our implemention of fclose()
int fclose(FILE *fp) {
if (fclose_shall_fail_on_EINTR) {
errno = EINTR;
fclose_shall_fail_on_EINTR = false; //--- reset for next call
return EOF;
} else { return 0; }
}
//--- this is the "production" function to be tested
void uninterruptible_close(FILE *fp) {
// Given an open FILE *fp
while (fclose(fp)==EOF && errno==EINTR) {
errno = 0;
}
}
char *test_non_interrupted_fclose(void) {
FILE *theHandle = NULL; //--- don't care here
uninterruptible_close(theHandle);
mu_assert("test fclose wo/ interruption", 0 == errno);
return 0;
}
char *test_interrupted_fclose(void) {
FILE *theHandle = NULL; //--- don't care here
fclose_shall_fail_on_EINTR = true;
uninterruptible_close(theHandle);
mu_assert("test fclose wo/ interruption", 0 == errno);
return 0;
}
char *test_suite(void)
{
mu_run_test(test_non_interrupted_fclose);
mu_run_test(test_interrupted_fclose);
return 0;
}
int main(int ac, char **av)
{
char *result = test_suite();
printf("number of tests run: %d\n", tests_run);
if (result) { printf("FAIL: %s\n", result); }
return 0 != result;
}