diff options
author | Paul Smith <psmith@gnu.org> | 2013-04-16 00:35:48 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2013-04-16 01:03:59 -0400 |
commit | b5d017c6241ac356915b178d0a9588653d18d460 (patch) | |
tree | e101b46d62edb0881bb09fc5ddec6d6bd1ed891c /misc.c | |
parent | 79e9347892dd2b6caa246e18fe050583da744bd8 (diff) | |
download | gunmake-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.c | 79 |
1 files changed, 79 insertions, 0 deletions
@@ -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 |