Eric Blake wrote: > M4 needs to know if > anything was written to stderr, so that it can exit with non-zero status > if the cleanup of temp files failed for any reason.
You really want m4 to exit with non-zero status just because it couldn't clean up in /tmp? Oh well. It's implementable. 2006-10-06 Bruno Haible <[EMAIL PROTECTED]> * clean-temp.h (cleanup_temp_file, cleanup_temp_subdir, cleanup_temp_dir_contents, cleanup_temp_dir): Change return type to int. * clean-temp.c (do_unlink, do_rmdir, cleanup_temp_file, cleanup_temp_subdir, cleanup_temp_dir_contents, cleanup_temp_dir): Return an error indicator. Suggested by Eric Blake. diff -c -3 -r1.2 clean-temp.h *** clean-temp.h 6 Oct 2006 12:17:22 -0000 1.2 --- clean-temp.h 6 Oct 2006 21:34:46 -0000 *************** *** 89,108 **** extern void unregister_temp_subdir (struct temp_dir *dir, const char *absolute_dir_name); ! /* Remove the given ABSOLUTE_FILE_NAME and unregister it. */ ! extern void cleanup_temp_file (struct temp_dir *dir, ! const char *absolute_file_name); ! ! /* Remove the given ABSOLUTE_DIR_NAME and unregister it. */ ! extern void cleanup_temp_subdir (struct temp_dir *dir, ! const char *absolute_dir_name); ! ! /* Remove all registered files and subdirectories inside DIR. */ ! extern void cleanup_temp_dir_contents (struct temp_dir *dir); /* Remove all registered files and subdirectories inside DIR and DIR itself. ! DIR cannot be used any more after this call. */ ! extern void cleanup_temp_dir (struct temp_dir *dir); /* Open a temporary file in a temporary directory. Registers the resulting file descriptor to be closed. */ --- 89,112 ---- extern void unregister_temp_subdir (struct temp_dir *dir, const char *absolute_dir_name); ! /* Remove the given ABSOLUTE_FILE_NAME and unregister it. ! Return 0 upon success, or -1 if there was some problem. */ ! extern int cleanup_temp_file (struct temp_dir *dir, ! const char *absolute_file_name); ! ! /* Remove the given ABSOLUTE_DIR_NAME and unregister it. ! Return 0 upon success, or -1 if there was some problem. */ ! extern int cleanup_temp_subdir (struct temp_dir *dir, ! const char *absolute_dir_name); ! ! /* Remove all registered files and subdirectories inside DIR. ! Return 0 upon success, or -1 if there was some problem. */ ! extern int cleanup_temp_dir_contents (struct temp_dir *dir); /* Remove all registered files and subdirectories inside DIR and DIR itself. ! DIR cannot be used any more after this call. ! Return 0 upon success, or -1 if there was some problem. */ ! extern int cleanup_temp_dir (struct temp_dir *dir); /* Open a temporary file in a temporary directory. Registers the resulting file descriptor to be closed. */ diff -c -3 -r1.4 clean-temp.c *** clean-temp.c 6 Oct 2006 21:20:20 -0000 1.4 --- clean-temp.c 6 Oct 2006 21:34:46 -0000 *************** *** 408,455 **** } } ! /* Remove a file, with optional error message. */ ! static void do_unlink (struct temp_dir *dir, const char *absolute_file_name) { if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose && errno != ENOENT) ! error (0, errno, _("cannot remove temporary file %s"), absolute_file_name); } ! /* Remove a directory, with optional error message. */ ! static void do_rmdir (struct temp_dir *dir, const char *absolute_dir_name) { if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose && errno != ENOENT) ! error (0, errno, ! _("cannot remove temporary directory %s"), absolute_dir_name); } ! /* Remove the given ABSOLUTE_FILE_NAME and unregister it. */ ! void cleanup_temp_file (struct temp_dir *dir, const char *absolute_file_name) { ! do_unlink (dir, absolute_file_name); unregister_temp_file (dir, absolute_file_name); } ! /* Remove the given ABSOLUTE_DIR_NAME and unregister it. */ ! void cleanup_temp_subdir (struct temp_dir *dir, const char *absolute_dir_name) { ! do_rmdir (dir, absolute_dir_name); unregister_temp_subdir (dir, absolute_dir_name); } ! /* Remove all registered files and subdirectories inside DIR. */ ! void cleanup_temp_dir_contents (struct temp_dir *dir) { struct tempdir *tmpdir = (struct tempdir *)dir; gl_list_t list; gl_list_iterator_t iter; const void *element; --- 408,477 ---- } } ! /* Remove a file, with optional error message. ! Return 0 upon success, or -1 if there was some problem. */ ! static int do_unlink (struct temp_dir *dir, const char *absolute_file_name) { if (unlink (absolute_file_name) < 0 && dir->cleanup_verbose && errno != ENOENT) ! { ! error (0, errno, _("cannot remove temporary file %s"), absolute_file_name); ! return -1; ! } ! return 0; } ! /* Remove a directory, with optional error message. ! Return 0 upon success, or -1 if there was some problem. */ ! static int do_rmdir (struct temp_dir *dir, const char *absolute_dir_name) { if (rmdir (absolute_dir_name) < 0 && dir->cleanup_verbose && errno != ENOENT) ! { ! error (0, errno, ! _("cannot remove temporary directory %s"), absolute_dir_name); ! return -1; ! } ! return 0; } ! /* Remove the given ABSOLUTE_FILE_NAME and unregister it. ! Return 0 upon success, or -1 if there was some problem. */ ! int cleanup_temp_file (struct temp_dir *dir, const char *absolute_file_name) { ! int err; ! ! err = do_unlink (dir, absolute_file_name); unregister_temp_file (dir, absolute_file_name); + + return err; } ! /* Remove the given ABSOLUTE_DIR_NAME and unregister it. ! Return 0 upon success, or -1 if there was some problem. */ ! int cleanup_temp_subdir (struct temp_dir *dir, const char *absolute_dir_name) { ! int err; ! ! err = do_rmdir (dir, absolute_dir_name); unregister_temp_subdir (dir, absolute_dir_name); + + return err; } ! /* Remove all registered files and subdirectories inside DIR. ! Return 0 upon success, or -1 if there was some problem. */ ! int cleanup_temp_dir_contents (struct temp_dir *dir) { struct tempdir *tmpdir = (struct tempdir *)dir; + int err = 0; gl_list_t list; gl_list_iterator_t iter; const void *element; *************** *** 462,468 **** { char *file = (char *) element; ! do_unlink (dir, file); gl_list_remove_node (list, node); /* Now only we can free file. */ free (file); --- 484,490 ---- { char *file = (char *) element; ! err |= do_unlink (dir, file); gl_list_remove_node (list, node); /* Now only we can free file. */ free (file); *************** *** 476,499 **** { char *subdir = (char *) element; ! do_rmdir (dir, subdir); gl_list_remove_node (list, node); /* Now only we can free subdir. */ free (subdir); } gl_list_iterator_free (&iter); } /* Remove all registered files and subdirectories inside DIR and DIR itself. ! DIR cannot be used any more after this call. */ ! void cleanup_temp_dir (struct temp_dir *dir) { struct tempdir *tmpdir = (struct tempdir *)dir; size_t i; ! cleanup_temp_dir_contents (dir); ! do_rmdir (dir, tmpdir->dirname); for (i = 0; i < cleanup_list.tempdir_count; i++) if (cleanup_list.tempdir_list[i] == tmpdir) --- 498,525 ---- { char *subdir = (char *) element; ! err |= do_rmdir (dir, subdir); gl_list_remove_node (list, node); /* Now only we can free subdir. */ free (subdir); } gl_list_iterator_free (&iter); + + return err; } /* Remove all registered files and subdirectories inside DIR and DIR itself. ! DIR cannot be used any more after this call. ! Return 0 upon success, or -1 if there was some problem. */ ! int cleanup_temp_dir (struct temp_dir *dir) { struct tempdir *tmpdir = (struct tempdir *)dir; + int err = 0; size_t i; ! err |= cleanup_temp_dir_contents (dir); ! err |= do_rmdir (dir, tmpdir->dirname); for (i = 0; i < cleanup_list.tempdir_count; i++) if (cleanup_list.tempdir_list[i] == tmpdir) *************** *** 510,516 **** /* Now only we can free the tmpdir->dirname and tmpdir itself. */ free (tmpdir->dirname); free (tmpdir); ! return; } /* The user passed an invalid DIR argument. */ --- 536,542 ---- /* Now only we can free the tmpdir->dirname and tmpdir itself. */ free (tmpdir->dirname); free (tmpdir); ! return err; } /* The user passed an invalid DIR argument. */