m4-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: add some fd tests to head


From: Eric Blake
Subject: Re: add some fd tests to head
Date: Wed, 8 Nov 2006 00:35:16 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> 
> Eric Blake <ebb9 <at> byu.net> writes:
> 
> > 
> > 2006-10-06  Eric Blake  <ebb9 <at> byu.net>
> > 
> >     Replace uses of tmpfile with clean-temp, since tmpfile is
> >     incompatible with closeout.
> 
> This was relatively easy to port to the branch (although it breaks mingw 
builds 
> unless a pending patch of mine is accepted in gnulib).

My clean-temp usage is still buggy on mingw and cygwin.  m4exit tried to remove 
the temporary directory while spilled diversions had open file descriptors, 
which is a no-no on Windows.  This is the patch for head; I'll have to backport 
it to the branch before 1.4.8:

2006-11-07  Eric Blake  <address@hidden>

        * tests/builtins.at (m4exit): New test; failed on cygwin before
        this patch.
        * m4/output.c (cleanup_tmpfile): Close files before removing
        directory.
        (make_room_for): Ensure that m4_error sees consistent state.

Index: tests/builtins.at
===================================================================
RCS file: /sources/m4/m4/tests/builtins.at,v
retrieving revision 1.31
diff -u -r1.31 builtins.at
--- tests/builtins.at   7 Nov 2006 19:18:10 -0000       1.31
+++ tests/builtins.at   8 Nov 2006 00:15:56 -0000
@@ -545,6 +545,25 @@
 AT_CLEANUP
 
 
+## ------ ##
+## m4exit ##
+## ------ ##
+
+AT_SETUP([m4exit])
+
+dnl Ensure that spilled diversions are gracefully cleaned up
+AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
+m4exit
+]])
+AT_CHECK([rm -Rf tmpdir && mkdir tmpdir && test -d tmpdir])
+TMPDIR=tmpdir
+export TMPDIR
+AT_CHECK_M4([in.m4], [0])
+AT_CHECK([rmdir tmpdir])
+
+AT_CLEANUP
+
+
 ## ------- ##
 ## mkdtemp ##
 ## ------- ##
Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.35
diff -u -r1.35 output.c
--- m4/output.c 27 Oct 2006 04:03:28 -0000      1.35
+++ m4/output.c 8 Nov 2006 00:15:56 -0000
@@ -165,6 +165,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 +282,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;
       selected_diversion->u.file = m4_tmpfile (context);
+      total_buffer_size -= selected_diversion->size;
+      selected_diversion->size = 0;
+
       if (set_cloexec_flag (fileno (selected_diversion->u.file), true) != 0)
        m4_error (context, 0, errno,
                  _("cannot protect diversion across forks"));
@@ -283,9 +307,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;
     }
 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]