malloca-instead-of-local_alloc.patch from patch #6230.
[pspp] / src / data / file-name.c
index cfe91932414e0c4bec928c89cb6efebd043f93ae..82279f77b1e2676d5c3e41915b60e734fde64dea 100644 (file)
 
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "intprops.h"
 #include "minmax.h"
 #include "dirname.h"
+#include "xmalloca.h"
 
-#include <libpspp/alloc.h>
 #include <libpspp/message.h>
 #include <data/settings.h>
 #include <libpspp/str.h>
 #include <libpspp/verbose-msg.h>
 #include <libpspp/version.h>
 
+#include "xalloc.h"
+
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
@@ -252,7 +256,7 @@ safety_violation (const char *fn)
 FILE *
 fn_open (const char *fn, const char *mode)
 {
-  assert (mode[0] == 'r' || mode[0] == 'w');
+  assert (mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a');
 
   if (mode[0] == 'r' && (!strcmp (fn, "stdin") || !strcmp (fn, "-")))
     return stdin;
@@ -277,13 +281,13 @@ fn_open (const char *fn, const char *mode)
       if (get_safer_mode ())
        return safety_violation (fn);
 
-      s = local_alloc (strlen (fn));
+      s = xmalloca (strlen (fn));
       memcpy (s, fn, strlen (fn) - 1);
       s[strlen (fn) - 1] = 0;
 
       f = popen (s, mode[0] == 'r' ? "r" : "w");
 
-      local_free (s);
+      freea (s);
 
       return f;
     }
@@ -320,6 +324,30 @@ fn_close (const char *fn, FILE *f)
     return fclose (f);
 }
 
+/* Creates a new file named FN with the given PERMISSIONS bits,
+   and returns a stream for it or a null pointer on failure.
+   MODE should be "w" or "wb". */
+FILE *
+create_stream (const char *fn, const char *mode, mode_t permissions)
+{
+  int fd;
+  FILE *stream;
+
+  fd = open (fn, O_WRONLY | O_CREAT | O_TRUNC, permissions);
+  if (fd < 0)
+    return NULL;
+
+  stream = fdopen (fd, mode);
+  if (stream == NULL)
+    {
+      int save_errno = errno;
+      close (fd);
+      errno = save_errno;
+    }
+
+  return stream;
+}
+
 #if !(defined _WIN32 || defined __WIN32__)
 /* A file's identity. */
 struct file_identity