[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/m4/output.c,v
From: |
Eric Blake |
Subject: |
Changes to m4/m4/output.c,v |
Date: |
Wed, 08 Nov 2006 04:26:54 +0000 |
CVSROOT: /sources/m4
Module name: m4
Changes by: Eric Blake <ericb> 06/11/08 04:26:53
Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- m4/output.c 27 Oct 2006 04:03:28 -0000 1.35
+++ m4/output.c 8 Nov 2006 04:26:53 -0000 1.36
@@ -148,9 +148,14 @@
m4_output_exit (void)
{
m4_diversion *diversion = free_list;
+ gl_list_t table = diversion_table;
+
+ /* Order is important, since we may have registered cleanup_tmpfile
+ as an atexit handler, and it must not traverse stale memory. */
assert (gl_list_size (diversion_table) == 1);
- free ((void *) gl_list_get_at (diversion_table, 0));
- gl_list_free (diversion_table);
+ diversion_table = NULL;
+ free ((void *) gl_list_get_at (table, 0));
+ gl_list_free (table);
while (diversion)
{
m4_diversion *stale = diversion;
@@ -165,6 +170,25 @@
static void
cleanup_tmpfile (void)
{
+ /* Close any open diversions. */
+ m4_diversion *diversion;
+ gl_list_iterator_t iter;
+ const void *elt;
+
+ if (diversion_table)
+ {
+ iter = gl_list_iterator_from_to (diversion_table, 1,
+ gl_list_size (diversion_table));
+ while (gl_list_iterator_next (&iter, &elt, NULL))
+ {
+ diversion = (m4_diversion *) elt;
+ if (!diversion->size && diversion->u.file)
+ close_stream_temp (diversion->u.file);
+ }
+ gl_list_iterator_free (&iter);
+ }
+
+ /* Clean up the temporary directory. */
if (cleanup_temp_dir (output_temp_dir) != 0)
_exit (exit_failure);
}
@@ -263,10 +287,15 @@
gl_list_iterator_free (&iter);
/* Create a temporary file, write the in-memory buffer of the
- diversion to this file, then release the buffer. */
+ diversion to this file, then release the buffer. Set the
+ size to zero before doing anything that can exit (), so that
+ the atexit handler recognizes a file that must be closed. */
selected_buffer = selected_diversion->u.buffer;
+ total_buffer_size -= selected_diversion->size;
+ selected_diversion->size = 0;
selected_diversion->u.file = m4_tmpfile (context);
+
if (set_cloexec_flag (fileno (selected_diversion->u.file), true) != 0)
m4_error (context, 0, errno,
_("cannot protect diversion across forks"));
@@ -283,9 +312,6 @@
/* Reclaim the buffer space for other diversions. */
free (selected_buffer);
- total_buffer_size -= selected_diversion->size;
-
- selected_diversion->size = 0;
selected_diversion->used = 0;
}
- Changes to m4/m4/output.c,v,
Eric Blake <=
- Changes to m4/m4/output.c,v, Eric Blake, 2006/11/08
- Changes to m4/m4/output.c,v, Eric Blake, 2006/11/11
- Changes to m4/m4/output.c,v, Eric Blake, 2006/11/14
- Changes to m4/m4/output.c,v, Eric Blake, 2006/11/14