m4-commit
[Top][All Lists]
Advanced

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

Changes to m4/src/Attic/output.c,v [branch-1_4]


From: Eric Blake
Subject: Changes to m4/src/Attic/output.c,v [branch-1_4]
Date: Fri, 13 Oct 2006 22:25:34 +0000

CVSROOT:        /sources/m4
Module name:    m4
Branch:         branch-1_4
Changes by:     Eric Blake <ericb>      06/10/13 22:25:32

Index: src/output.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/output.c,v
retrieving revision 1.1.1.1.2.10
retrieving revision 1.1.1.1.2.11
diff -u -b -r1.1.1.1.2.10 -r1.1.1.1.2.11
--- src/output.c        18 Aug 2006 23:11:37 -0000      1.1.1.1.2.10
+++ src/output.c        13 Oct 2006 22:25:32 -0000      1.1.1.1.2.11
@@ -77,6 +77,13 @@
 /* Number of input line we are generating output for.  */
 int output_current_line;
 
+typedef struct temp_dir m4_temp_dir;
+
+/* Temporary directory holding all spilled diversion files.  */
+static m4_temp_dir *output_temp_dir;
+
+
+
 /*------------------------.
 | Output initialisation.  |
 `------------------------*/
@@ -99,6 +106,48 @@
   output_unused = 0;
 }
 
+/* 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)
+{
+  if (cleanup_temp_dir (output_temp_dir) != 0)
+    _exit (exit_failure);
+}
+
+/* Create a temporary file open for reading and writing in a secure
+   temp directory.  The file will be automatically closed and deleted
+   on a fatal signal.  When done with the file, close it with
+   close_stream_temp.  Exits on failure, so the return value is always
+   an open file.  */
+static FILE *
+m4_tmpfile (void)
+{
+  static unsigned int count;
+  char *name;
+  FILE *file;
+
+  if (output_temp_dir == NULL)
+    {
+      errno = 0;
+      output_temp_dir = create_temp_dir ("m4-", NULL, true);
+      if (output_temp_dir == NULL)
+       M4ERROR ((EXIT_FAILURE, errno,
+                 "cannot create temporary file for diversion"));
+      atexit (cleanup_tmpfile);
+    }
+  name = xasprintf ("%s/m4-%d", output_temp_dir->dir_name, count++);
+  register_temp_file (output_temp_dir, name);
+  errno = 0;
+  file = fopen_temp (name, O_BINARY ? "wb+" : "w+");
+  if (file == NULL)
+    M4ERROR ((EXIT_FAILURE, errno,
+             "cannot create temporary file for diversion"));
+  free (name);
+  return file;
+}
+
 /*-----------------------------------------------------------------------.
 | Reorganize in-memory diversion buffers so the current diversion can   |
 | accomodate LENGTH more characters without further reorganization.  The |
@@ -154,10 +203,7 @@
       /* Create a temporary file, write the in-memory buffer of the
         diversion to this file, then release the buffer.  */
 
-      selected_diversion->file = tmpfile ();
-      if (selected_diversion->file == NULL)
-       M4ERROR ((EXIT_FAILURE, errno,
-                 "ERROR: cannot create temporary file for diversion"));
+      selected_diversion->file = m4_tmpfile ();
       if (set_cloexec_flag (fileno (selected_diversion->file), true) != 0)
        M4ERROR ((warning_status, errno,
                  "Warning: cannot protect diversion across forks"));
@@ -485,7 +531,7 @@
 
   if (diversion->file)
     {
-      fclose (diversion->file);
+      close_stream_temp (diversion->file);
       diversion->file = NULL;
     }
   else if (diversion->buffer)




reply via email to

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