Así es como lo probaría, por el mero hecho de probarlo, ya que fizzer nos recordó que llamar al fclose()
dos veces no es seguro.
Es posible redefinir fclose()
(o cualquier otra función de libc) en su programa con su propio comportamiento. En los sistemas tipo Unix, el enlazador no se queja, nunca lo intentó en Windows pero con cygwin. Por supuesto, esto evita que sus otras pruebas utilicen el fclose()
real, por lo tanto, dicha prueba debe colocarse en un archivo ejecutable de prueba separado.
Aquí hay un ejemplo todo-en-uno con minunit.
#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;
}
Básicamente está hablando de burlarse de las llamadas al sistema, que es lo que hay que hacer en este caso. – tvanfosson
Lamentablemente, se estaría burlando de la carne de lo que quiere probar. La pregunta es: ¿cuál es el estado de fp cuando la llamada al sistema * real * se interrumpe durante el cierre. – bmdhacks