summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Goncharov <dgoncharov@users.sf.net>2022-11-13 16:20:33 -0500
committerPaul Smith <psmith@gnu.org>2022-11-13 16:34:01 -0500
commit1b51ba1f5d448281ddeea5a252814bdec56a86fa (patch)
treefeb32c324984b4f3eeae9134811702c94f3d5090 /src
parent4c9d87f4ae938a20fc21d2a0538c74dad0518f20 (diff)
downloadmake-git-1b51ba1f5d448281ddeea5a252814bdec56a86fa.tar.gz
[SV 63333] Be more lenient when failing to create temporary files
If make cannot create a temporary lock file for output sync, continue without output sync enabled rather than dying. However, if make cannot store a makefile from stdin to a temporary file that is still a fatal error. * misc.c (get_tmppath): Keep running on failure to generate a temporary file name. (get_tmpfd): Keep running on failure to get a temporary file. (get_tmpfile): Keep running on failure to open a temporary file. Ensure memory is freed if we return an error. * posixos.c (os_anontmp): Keep running on failure to open an anonymous temporary file. * output.c (setup_tmpfile): Print an error on failure to create an output sync lock file. * main.c (main): Die on failure to store makefile from stdin to a temporary file. * tests/scripts/features/output-sync: Add tests. * tests/scripts/features/temp_stdin: Ditto.
Diffstat (limited to 'src')
-rw-r--r--src/main.c3
-rw-r--r--src/misc.c64
-rw-r--r--src/output.c3
-rw-r--r--src/posixos.c7
4 files changed, 57 insertions, 20 deletions
diff --git a/src/main.c b/src/main.c
index f2caf7a8..78729de1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1928,6 +1928,9 @@ main (int argc, char **argv, char **envp)
_("Makefile from standard input specified twice"));
outfile = get_tmpfile (&newnm);
+ if (!outfile)
+ O (fatal, NILF,
+ _("cannot store makefile from stdin to a temporary file"));
while (!feof (stdin) && ! ferror (stdin))
{
diff --git a/src/misc.c b/src/misc.c
index 8264fe9f..00dce749 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -20,8 +20,7 @@ this program. If not, see <https://www.gnu.org/licenses/>. */
#include "os.h"
#include "debug.h"
-/* GNU make no longer supports pre-ANSI89 environments. */
-
+#include <assert.h>
#include <stdarg.h>
#ifdef WINDOWS32
@@ -650,11 +649,19 @@ get_tmppath ()
# ifdef HAVE_MKTEMP
path = get_tmptemplate ();
if (*mktemp (path) == '\0')
- pfatal_with_name ("mktemp");
+ {
+ OSS (error, NILF,
+ _("cannot generate temp path from %s: %s"), path, strerror (errno));
+ return NULL;
+ }
# else
path = xmalloc (L_tmpnam + 1);
if (tmpnam (path) == NULL)
- pfatal_with_name ("tmpnam");
+ {
+ OS (error, NILF,
+ _("cannot generate temp name: %s"), strerror (errno));
+ return NULL;
+ }
# endif
return path;
@@ -662,7 +669,9 @@ get_tmppath ()
#endif
/* Generate a temporary file and return an fd for it. If name is NULL then
- the temp file is anonymous and will be deleted when the process exits. */
+ the temp file is anonymous and will be deleted when the process exits. If
+ name is not null then *name will point to an allocated buffer, or set to
+ NULL on failure. */
int
get_tmpfd (char **name)
{
@@ -670,9 +679,11 @@ get_tmpfd (char **name)
char *tmpnm;
mode_t mask;
- /* If there's an os-specific way to get an anoymous temp file use it. */
- if (!name)
+ if (name)
+ *name = NULL;
+ else
{
+ /* If there's an os-specific way to get an anoymous temp file use it. */
fd = os_anontmp ();
if (fd >= 0)
return fd;
@@ -689,13 +700,19 @@ get_tmpfd (char **name)
EINTRLOOP (fd, mkstemp (tmpnm));
#else
tmpnm = get_tmppath ();
+ if (!tmpnm)
+ return -1;
/* Can't use mkstemp(), but try to guard against a race condition. */
EINTRLOOP (fd, open (tmpnm, O_CREAT|O_EXCL|O_RDWR, 0600));
#endif
if (fd < 0)
- OSS (fatal, NILF,
- _("create temporary file %s: %s"), tmpnm, strerror (errno));
+ {
+ OSS (error, NILF,
+ _("cannot create temporary file %s: %s"), tmpnm, strerror (errno));
+ free (tmpnm);
+ return -1;
+ }
if (name)
*name = tmpnm;
@@ -704,8 +721,8 @@ get_tmpfd (char **name)
int r;
EINTRLOOP (r, unlink (tmpnm));
if (r < 0)
- OSS (fatal, NILF,
- _("unlink temporary file %s: %s"), tmpnm, strerror (errno));
+ OSS (error, NILF,
+ _("cannot unlink temporary file %s: %s"), tmpnm, strerror (errno));
free (tmpnm);
}
@@ -715,8 +732,8 @@ get_tmpfd (char **name)
}
/* Return a FILE* for a temporary file, opened in the safest way possible.
- Set name to point to an allocated buffer containing the name of the file.
- Note, this cannot be NULL! */
+ Set name to point to an allocated buffer containing the name of the file,
+ or NULL on failure. Note, name cannot be NULL! */
FILE *
get_tmpfile (char **name)
{
@@ -725,26 +742,37 @@ get_tmpfile (char **name)
FILE *file;
#if defined(HAVE_FDOPEN)
- int fd = get_tmpfd (name);
+ int fd;
+ assert (name);
+ fd = get_tmpfd (name);
+ if (fd < 0)
+ return NULL;
+ assert (*name);
ENULLLOOP (file, fdopen (fd, tmpfile_mode));
if (file == NULL)
- OSS (fatal, NILF,
+ OSS (error, NILF,
_("fdopen: temporary file %s: %s"), *name, strerror (errno));
#else
/* Preserve the current umask, and set a restrictive one for temp files. */
mode_t mask = umask (0077);
- int err;
+ assert (name);
*name = get_tmppath ();
+ if (!*name)
+ return NULL;
/* Although this fopen is insecure, it is executed only on non-fdopen
platforms, which should be a rarity nowadays. */
ENULLLOOP (file, fopen (*name, tmpfile_mode));
if (file == NULL)
- OSS (fatal, NILF,
- _("fopen: temporary file %s: %s"), *name, strerror (errno));
+ {
+ OSS (error, NILF,
+ _("fopen: temporary file %s: %s"), *name, strerror (errno));
+ free (*name);
+ *name = NULL;
+ }
umask (mask);
#endif
diff --git a/src/output.c b/src/output.c
index 43eb2f06..22387dff 100644
--- a/src/output.c
+++ b/src/output.c
@@ -248,6 +248,9 @@ setup_tmpfile (struct output *out)
/* If we failed to create a temp file, disable output sync going forward. */
error:
+ O (error, NILF,
+ _("cannot open output-sync lock file, suppressing output-sync."));
+
output_close (out);
output_sync = OUTPUT_SYNC_NONE;
osync_clear ();
diff --git a/src/posixos.c b/src/posixos.c
index 3d7d6614..78358dd8 100644
--- a/src/posixos.c
+++ b/src/posixos.c
@@ -872,12 +872,15 @@ os_anontmp ()
FILE *tfile;
ENULLLOOP (tfile, tmpfile ());
if (!tfile)
- pfatal_with_name ("tmpfile");
+ {
+ OS (error, NILF, "tmpfile: %s", strerror (errno));
+ return -1;
+ }
umask (mask);
EINTRLOOP (fd, dup (fileno (tfile)));
if (fd < 0)
- pfatal_with_name ("dup");
+ OS (error, NILF, "dup: %s", strerror (errno));
fclose (tfile);
}
#endif