#include #include #include #include #define with_open_file(var, path, mode) \ /* loop control */ \ for (int with_open_file_run = 1; \ with_open_file_run; ) \ /* save path, so that it is only evaluated once. */ \ for (char *with_open_file_path = (path); \ with_open_file_run; ) \ /* open the file and setup the cleanup */ \ for (FILE *with_open_file_file \ __attribute__((cleanup (with_open_file_cleanup))) \ = fopen (with_open_file_path, (mode)); \ with_open_file_run; ) \ /* call helper function to crash and burn, when \ the file could not be opened. */ \ for (with_open_file_ensure (with_open_file_file, \ with_open_file_path); \ with_open_file_run; ) \ /* define the given var and bind it to the file */ \ for (FILE *var = with_open_file_file; \ with_open_file_run; \ with_open_file_run = 0) /* all done */ static void with_open_file_cleanup (FILE **f) { if (*f) fclose (*f); } static void with_open_file_ensure (FILE *f, const char *path) { if (!f) { fprintf (stderr, "Cannot open file \"%s\": %s\n", path, strerror (errno)); exit (1); } } /* -- Demo ----------------------------------------------------------------- */ int main (int argc, char **argv) { if (argc != 2) { fprintf (stderr, "Supply a file name as command line argument.\n"); exit (1); } with_open_file (f, argv[1], "r") { printf ("File is open: f = %p\n", f); } return 0; }