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 05:05:58 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

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

> 
> 2006-11-07  Eric Blake  <ebb9 <at> byu.net>
> 
>       * 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.

And this followup.

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

        * m4/output.c (cleanup_tmpfile, m4_insert_diversion_helper): Check
        for failure.

Index: m4/output.c
===================================================================
RCS file: /sources/m4/m4/m4/output.c,v
retrieving revision 1.36
diff -u -r1.36 output.c
--- m4/output.c 8 Nov 2006 04:26:53 -0000       1.36
+++ m4/output.c 8 Nov 2006 05:02:55 -0000
@@ -174,6 +174,7 @@
   m4_diversion *diversion;
   gl_list_iterator_t iter;
   const void *elt;
+  bool fail = false;
 
   if (diversion_table)
     {
@@ -182,14 +183,21 @@
       while (gl_list_iterator_next (&iter, &elt, NULL))
        {
          diversion = (m4_diversion *) elt;
-         if (!diversion->size && diversion->u.file)
-           close_stream_temp (diversion->u.file);
+         if (!diversion->size && diversion->u.file &&
+             close_stream_temp (diversion->u.file) != 0)
+           {
+             error (0, errno,
+                    _("cannot clean temporary file for diversion"));
+             fail = true;
+           }
        }
       gl_list_iterator_free (&iter);
     }
 
   /* Clean up the temporary directory.  */
   if (cleanup_temp_dir (output_temp_dir) != 0)
+    fail = true;
+  if (fail)
     _exit (exit_failure);
 }
 
@@ -664,8 +672,9 @@
       diversion->size = 0;
       diversion->used = 0;
     }
-  else if (diversion->u.file)
-    close_stream_temp (diversion->u.file);
+  else if (diversion->u.file && close_stream_temp (diversion->u.file) != 0)
+    m4_error (context, 0, errno,
+             _("cannot clean temporary file for diversion"));
   gl_list_remove_node (diversion_table, node);
   diversion->u.next = free_list;
   free_list = diversion;


Today's patches ported to the branch as follows.

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

        * src/m4.h (output_exit): New prototype.
        * src/m4.c (main): Use it.
        * src/output.c (cleanup_tmpfile): Close files before removing
        directory.
        (insert_diversion): Check for failure.
        (output_exit): Avoid memory leak.
        * doc/m4.texinfo (Diversions): Test this bug.

Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.98
diff -u -r1.1.1.1.2.98 m4.texinfo
--- doc/m4.texinfo      7 Nov 2006 19:14:03 -0000       1.1.1.1.2.98
+++ doc/m4.texinfo      8 Nov 2006 05:01:34 -0000
@@ -3621,6 +3621,38 @@
 divert(`-1')undivert
 @end example
 
address@hidden Another test of spilled diversions.
+
address@hidden
+divert(`-1')define(`f', `.')
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+define(`f', defn(`f')defn(`f'))
+divert`'dnl
+len(f)
address@hidden
+divert(`1')
+f
+m4exit
address@hidden example
+
 @comment We also need to test allocation overflow.  On 32-bit
 @comment platforms, this should fail outright.  But on 64-bit platforms
 @comment with enough memory, the allocation might succeed (hopefully
Index: src/m4.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/m4.c,v
retrieving revision 1.1.1.1.2.37
diff -u -r1.1.1.1.2.37 m4.c
--- src/m4.c    1 Nov 2006 22:29:08 -0000       1.1.1.1.2.37
+++ src/m4.c    8 Nov 2006 05:01:34 -0000
@@ -576,5 +576,6 @@
       make_diversion (0);
       undivert_all ();
     }
+  output_exit ();
   exit (retcode);
 }
Index: src/m4.h
===================================================================
RCS file: /sources/m4/m4/src/m4.h,v
retrieving revision 1.1.1.1.2.33
diff -u -r1.1.1.1.2.33 m4.h
--- src/m4.h    1 Nov 2006 22:29:08 -0000       1.1.1.1.2.33
+++ src/m4.h    8 Nov 2006 05:01:34 -0000
@@ -311,6 +311,7 @@
 extern int output_current_line;
 
 void output_init (void);
+void output_exit (void);
 void shipout_text (struct obstack *, const char *, int);
 void make_diversion (int);
 void insert_diversion (int);
Index: src/output.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/output.c,v
retrieving revision 1.1.1.1.2.14
diff -u -r1.1.1.1.2.14 output.c
--- src/output.c        1 Nov 2006 22:29:08 -0000       1.1.1.1.2.14
+++ src/output.c        8 Nov 2006 05:01:34 -0000
@@ -106,13 +106,39 @@
   output_unused = 0;
 }
 
+void
+output_exit (void)
+{
+  free (diversion_table);
+  diversion_table = NULL;
+}
+
 /* Clean up any temporary directory.  Designed for use as an atexit
    handler, where it is not safe to call exit() recursively; so this
    calls _exit if a problem is encountered.  */
 static void
 cleanup_tmpfile (void)
 {
+  /* Close any open diversions.  */
+  int divnum;
+  struct diversion *diversion;
+  bool fail = false;
+
+  if (diversion_table)
+    for (divnum = 1; divnum < diversions; divnum++)
+      {
+       diversion = diversion_table + divnum;
+       if (diversion->file && close_stream_temp (diversion->file) != 0)
+         {
+           M4ERROR ((0, errno, "cannot clean temporary file for diversion"));
+           fail = true;
+         }
+      }
+
+  /* Clean up the temporary directory.  */
   if (cleanup_temp_dir (output_temp_dir) != 0)
+    fail = true;
+  if (fail)
     _exit (exit_failure);
 }
 
@@ -531,7 +557,8 @@
 
   if (diversion->file)
     {
-      close_stream_temp (diversion->file);
+      if (close_stream_temp (diversion->file) != 0)
+       M4ERROR ((0, errno, "cannot clean temporary file for diversion"));
       diversion->file = NULL;
     }
   else if (diversion->buffer)






reply via email to

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