summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2013-04-16 00:35:48 -0400
committerPaul Smith <psmith@gnu.org>2013-04-16 01:03:59 -0400
commitb5d017c6241ac356915b178d0a9588653d18d460 (patch)
treee101b46d62edb0881bb09fc5ddec6d6bd1ed891c /misc.c
parent79e9347892dd2b6caa246e18fe050583da744bd8 (diff)
downloadgunmake-b5d017c6241ac356915b178d0a9588653d18d460.tar.gz
Create an open_tmpfd() function to return temp files by FD. Use it.
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/misc.c b/misc.c
index df208a6..800e857 100644
--- a/misc.c
+++ b/misc.c
@@ -930,6 +930,85 @@ get_path_max (void)
#endif
+/* Provide support for temporary files. */
+
+#ifndef HAVE_STDLIB_H
+# ifdef HAVE_MKSTEMP
+int mkstemp (char *template);
+# else
+char *mktemp (char *template);
+# endif
+#endif
+
+/* This is only used by output-sync, and it may not be portable to Windows. */
+#ifdef OUTPUT_SYNC
+
+/* Returns a file descriptor to a temporary file. The file is automatically
+ closed/deleted on exit. Don't use a FILE* stream. */
+int
+open_tmpfd()
+{
+ int fd = -1;
+ FILE *tfile = tmpfile();
+
+ if (! tfile)
+ pfatal_with_name ("tmpfile");
+
+ /* Create a duplicate so we can close the stream. */
+ fd = dup (fileno (tfile));
+ if (fd < 0)
+ pfatal_with_name ("dup");
+
+ fclose (tfile);
+
+ return fd;
+}
+
+#endif
+
+FILE *
+open_tmpfile(char **name, const char *template)
+{
+#ifdef HAVE_FDOPEN
+ int fd;
+#endif
+
+#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP
+# define TEMPLATE_LEN strlen (template)
+#else
+# define TEMPLATE_LEN L_tmpnam
+#endif
+ *name = xmalloc (TEMPLATE_LEN + 1);
+ strcpy (*name, template);
+
+#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN
+ /* It's safest to use mkstemp(), if we can. */
+ fd = mkstemp (*name);
+ if (fd == -1)
+ return 0;
+ return fdopen (fd, "w");
+#else
+# ifdef HAVE_MKTEMP
+ (void) mktemp (*name);
+# else
+ (void) tmpnam (*name);
+# endif
+
+# ifdef HAVE_FDOPEN
+ /* Can't use mkstemp(), but guard against a race condition. */
+ fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600);
+ if (fd == -1)
+ return 0;
+ return fdopen (fd, "w");
+# else
+ /* Not secure, but what can we do? */
+ return fopen (*name, "w");
+# endif
+#endif
+}
+
+
+
/* This code is stolen from gnulib.
If/when we abandon the requirement to work with K&R compilers, we can
remove this (and perhaps other parts of GNU make!) and migrate to using