diff --git a/tests/signal.c b/tests/signal.c index 57d1323e2c92e0b01bbf36541c449378d547950f..b192ad397def2bc139a0767e8a76480b1e0b5fc5 100644 --- a/tests/signal.c +++ b/tests/signal.c @@ -11,17 +11,13 @@ void handler(int sig) { } int main(void) { - if (signal(SIGUSR1, &handler) == SIG_ERR) { - puts("Signal error!"); - printf("%d\n", errno); - exit(EXIT_FAILURE); - } + void (*signal_status)(int) = signal(SIGUSR1, &handler); + ERROR_IF(signal, signal_status, == SIG_ERR); puts("Raising..."); - if (raise(SIGUSR1)) { - puts("Raise error!"); - printf("%d\n", errno); - exit(EXIT_FAILURE); - } + + int raise_status = raise(SIGUSR1); + ERROR_IF(raise, raise_status, < 0); + puts("Raised."); } diff --git a/tests/stdio/all.c b/tests/stdio/all.c index 2ccc35eb4131da5433722825a4515ca8dc408e43..de7c60ab63d8d346873ac87ec5f37bdd80f227c6 100644 --- a/tests/stdio/all.c +++ b/tests/stdio/all.c @@ -4,11 +4,26 @@ #include "test_helpers.h" int main(void) { - FILE *f = fopen("stdio/stdio.in", "r"); - printf("%c\n", fgetc(f)); - ungetc('H', f); - char *in = malloc(30); - printf("%s\n", fgets(in, 30, f)); - setvbuf(stdout, 0, _IONBF, 0); - printf("Hello\n"); + FILE *f = fopen("stdio/stdio.in", "r"); + ERROR_IF(fopen, f, == NULL); + + int c = fgetc(f); + ERROR_IF(fgetc, c, == EOF); + UNEXP_IF(fgetc, c, < 0); + UNEXP_IF(fgetc, c, > 255); + printf("%c\n", c); + + int u = ungetc('J', f); + ERROR_IF(ungetc, u, == EOF); + + char in[30] = { 0 }; + char *s = fgets(in, 30, f); + ERROR_IF(fgets, s, == NULL); + printf("%s\n", in); + + int vb = setvbuf(stdout, 0, _IONBF, 0); + //ERROR_IF(setvbuf, vb, > 0); // TODO: Cannot use this, doesn't set errno + //UNEXP_IF(setvbuf, vb, != 0); + + printf("Hello\n"); } diff --git a/tests/stdio/fgets.c b/tests/stdio/fgets.c index 6e2b715bf4eb44aa7755496bffebd59f0264103d..ed02999cde1b57a33373ac662e2e214dbb68333b 100644 --- a/tests/stdio/fgets.c +++ b/tests/stdio/fgets.c @@ -4,8 +4,9 @@ #include "test_helpers.h" int main(void) { - //FILE *f = fopen("/etc/ssl/certs/ca-certificates.crt", "r"); FILE *f = fopen("stdio/stdio.in", "r"); + ERROR_IF(fopen, f, == NULL); + char line[256]; while (1) { diff --git a/tests/stdio/fputs.c b/tests/stdio/fputs.c index 7d76d12ab1c9c3e9215581f06efb673e1bebbf53..e377bfe8dbea46b9e620337772e116e4689a0bfe 100644 --- a/tests/stdio/fputs.c +++ b/tests/stdio/fputs.c @@ -4,8 +4,16 @@ #include "test_helpers.h" int main(void) { - FILE *f = fopen("stdio/fputs.out", "w"); - char *in = "Hello World!"; - fputs(in, f); // calls fwrite, helpers::fwritex, internal::to_write and internal::stdio_write - fclose(f); + FILE *f = fopen("stdio/fputs.out", "w"); + ERROR_IF(fopen, f, == NULL); + + char *in = "Hello World!"; + + int p = fputs(in, f); + ERROR_IF(fputs, p, == EOF); + UNEXP_IF(fputs, p, < 0); + + int c = fclose(f); + ERROR_IF(fclose, c, == EOF); + UNEXP_IF(fclose, c, != 0); } diff --git a/tests/stdio/fread.c b/tests/stdio/fread.c index ea14368ebfb34fec36d91cff64082d4cf0ca4a3e..75eb7ff8f6dbb43f3cbe711b601f5a5c25f7e076 100644 --- a/tests/stdio/fread.c +++ b/tests/stdio/fread.c @@ -6,6 +6,7 @@ int main(void) { FILE *fp = fopen("stdio/fread.in", "rb"); + ERROR_IF(fopen, fp, == NULL); char buf[33] = { 0 }; for (int i = 1; i <= 32; ++i) { diff --git a/tests/stdio/fseek.c b/tests/stdio/fseek.c index c07cf79b58f1c94ca7848814556b219cd659a722..8bc948799d3e770d59d67fd58cf0a5174a6329b7 100644 --- a/tests/stdio/fseek.c +++ b/tests/stdio/fseek.c @@ -4,7 +4,9 @@ #include "test_helpers.h" int main(void) { - FILE *f = fopen("stdio/stdio.in", "r"); + FILE *f = fopen("stdio/stdio.in", "r"); + ERROR_IF(fopen, f, == NULL); + if (fseek(f, 14, SEEK_CUR) < 0) { puts("fseek error"); exit(EXIT_FAILURE); diff --git a/tests/stdio/fwrite.c b/tests/stdio/fwrite.c index 24c7040fb79789e69bf4305f5168f2a97d05fe10..308c9c296a4f3320b6ce61d39fc85377ccad5e20 100644 --- a/tests/stdio/fwrite.c +++ b/tests/stdio/fwrite.c @@ -5,21 +5,23 @@ #include "test_helpers.h" int main(void) { - FILE *f = fopen("stdio/fwrite.out", "w"); - const char ptr[] = "Hello World!"; + FILE *f = fopen("stdio/fwrite.out", "w"); + ERROR_IF(fopen, f, == NULL); - if (fwrite(ptr, 0, 17, f)) { - exit(EXIT_FAILURE); - } + const char ptr[] = "Hello World!"; - if (fwrite(ptr, 7, 0, f)) { - exit(EXIT_FAILURE); - } + if (fwrite(ptr, 0, 17, f)) { + exit(EXIT_FAILURE); + } - if (fwrite(ptr, 0, 0, f)) { - exit(EXIT_FAILURE); - } + if (fwrite(ptr, 7, 0, f)) { + exit(EXIT_FAILURE); + } - fwrite(ptr, sizeof(ptr), 1, f); - fclose(f); + if (fwrite(ptr, 0, 0, f)) { + exit(EXIT_FAILURE); + } + + fwrite(ptr, sizeof(ptr), 1, f); + fclose(f); } diff --git a/tests/stdio/mutex.c b/tests/stdio/mutex.c index aae45caa12bb315d707be6c14a673e838a43a12b..3d9be9d8db4dae346a36e6355d6c9eb83e410a1a 100644 --- a/tests/stdio/mutex.c +++ b/tests/stdio/mutex.c @@ -4,7 +4,8 @@ #include "test_helpers.h" int main(void) { - FILE* f = fopen("stdio/stdio.in", "r"); + FILE *f = fopen("stdio/stdio.in", "r"); + ERROR_IF(fopen, f, == NULL); flockfile(f); diff --git a/tests/stdio/popen.c b/tests/stdio/popen.c index 967ad78ace7bdf8cfa26d7a16377f668978840f5..3d314d52a1d333c8ca26e414c6b2d763b137cd95 100644 --- a/tests/stdio/popen.c +++ b/tests/stdio/popen.c @@ -4,27 +4,14 @@ #include "test_helpers.h" int main(void) { - FILE *fp; - int status; - char path[256]; - - - fp = popen("ls -1 example_dir", "r"); - if (fp == NULL) { - perror("popen"); - exit(EXIT_FAILURE); - } + FILE *fp = popen("ls -1 example_dir", "r"); + ERROR_IF(fopen, fp, == NULL); + char path[256] = { 0 }; while (fgets(path, 256, fp) != NULL) { printf("%s", path); } - - status = pclose(fp); - if (status == -1) { - perror("pclose"); - exit(EXIT_FAILURE); - } else { - printf("status %x\n", status); - } + int status = pclose(fp); + ERROR_IF(pclose, status, == -1); } diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 6db31e2d7a2b9f99282b9db1d14d766eec7dd1a1..d3559a4e53465df08c91e9d37bd51a5b2303c843 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -7,25 +7,67 @@ #include <string.h> #include <unistd.h> -// Throws an error on a well-defined error value. -// Don't pass functions as status or condition, it might evaluate them multiple times. +// Throws errors on a well-defined API error values. +// +// Only use with API functions that sets the errno variable. +// Do not pass functions as the status or condition arguments, they might be +// evaluated multiple times. +// +// Usage example: +// +// > Upon successful completion, fclose() returns 0. +// > Otherwise, it returns EOF and sets errno to indicate the error. +// +// int status = fclose(fp); +// ERROR_IF(fclose, status, == EOF); +// +// Use it only for checking the API error values. +// Do not use it for checking the correctness of the results. If you need to +// do that, print the values to the standard output and use the expected outputs +// directory. +// +// For example: +// +// int c = fgetc(f); // !!! DO NOT USE THIS WAY !!! +// ERROR_IF(fgetc, c, != 'H'); // !!! DO NOT USE THIS WAY !!! +// +// Correct usage: +// +// int c = fgetc(f); // OK +// ERROR_IF(fgetc, c, == EOF); // OK +// printf("result: %c\n", c); // OK +// #define ERROR_IF(func, status, condition) { \ if (status condition) { \ fprintf(stderr, "%s:%s:%d: '%s' returned an error: %s (%d)\n", \ __FILE__, __func__, __LINE__, #func, strerror(errno), errno); \ _exit(EXIT_FAILURE); \ - }\ + } \ } -// Throws an error on an return value not defined by the standards. -// Used for sanity checking the return values. -// Don't pass functions as status or condition it might evaluate them multiple times. +// Throws errors on API return values not defined by the standards. +// +// Do not pass functions as the status or condition arguments, they might be +// evaluated multiple times. +// +// Use it only for detecting return values that should have never been returned +// in any case by the API functions. +// +// Usage example: +// +// > The fgetc() function obtains the next byte as an unsigned char +// > converted to an int. +// +// int c = fgetc(f); +// UNEXP_IF(fgetc, c, < 0); +// UNEXP_IF(fgetc, c, > 255); +// #define UNEXP_IF(func, status, condition) { \ if (status condition) { \ fprintf(stderr, "%s:%s:%d: '%s' returned a non-standard value: %d\n", \ __FILE__, __func__, __LINE__, #func, status); \ _exit(EXIT_FAILURE); \ - }\ + } \ } // A convenience macro to show where the test fail. diff --git a/tests/waitpid.c b/tests/waitpid.c index e0b77829f4bb185b769832a6191338357a18ee99..ec4c6dedc621e7310a3bc6510d8e75512dd6fd97 100644 --- a/tests/waitpid.c +++ b/tests/waitpid.c @@ -6,6 +6,8 @@ int main(void) { pid_t pid = fork(); + ERROR_IF(fork, pid, == -1); + if (pid == 0) { // child sleep(1); @@ -13,6 +15,7 @@ int main(void) { } else { // parent int stat_loc; - waitpid(pid, &stat_loc, 0); + pid_t wid = waitpid(pid, &stat_loc, 0); + ERROR_IF(waitpid, wid, == -1); } }