aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c12
-rw-r--r--lib/lib.h1
-rw-r--r--lib/xwrap.c10
3 files changed, 15 insertions, 8 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 83e4db45..ea678011 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -700,18 +700,14 @@ static void tempfile_handler(void)
int copy_tempfile(int fdin, char *name, char **tempname)
{
struct stat statbuf;
- int fd;
- int ignored __attribute__((__unused__));
+ int fd = xtempfile(name, tempname), ignored __attribute__((__unused__));
- *tempname = xmprintf("%s%s", name, "XXXXXX");
- if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file");
+ // Record tempfile for exit cleanup if interrupted
if (!tempfile2zap) sigatexit(tempfile_handler);
tempfile2zap = *tempname;
- // Set permissions of output file (ignoring errors, usually due to nonroot)
-
- fstat(fdin, &statbuf);
- fchmod(fd, statbuf.st_mode);
+ // Set permissions of output file.
+ if (!fstat(fdin, &statbuf)) fchmod(fd, statbuf.st_mode);
// We chmod before chown, which strips the suid bit. Caller has to explicitly
// switch it back on if they want to keep suid.
diff --git a/lib/lib.h b/lib/lib.h
index 609210ac..676c47b3 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -138,6 +138,7 @@ int xrun(char **argv);
int xpspawn(char **argv, int*pipes);
void xaccess(char *path, int flags);
void xunlink(char *path);
+int xtempfile(char *name, char **tempname);
int xcreate(char *path, int flags, int mode);
int xopen(char *path, int flags);
int xcreate_stdio(char *path, int flags, int mode);
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 74da0ed1..562cbaf4 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -377,6 +377,16 @@ int notstdio(int fd)
return fd;
}
+int xtempfile(char *name, char **tempname)
+{
+ int fd;
+
+ *tempname = xmprintf("%s%s", name, "XXXXXX");
+ if(-1 == (fd = mkstemp(*tempname))) error_exit("no temp file");
+
+ return fd;
+}
+
// Create a file but don't return stdin/stdout/stderr
int xcreate(char *path, int flags, int mode)
{