diff --git a/include/fileutils.h b/include/fileutils.h index 27b566190..691429ba0 100644 --- a/include/fileutils.h +++ b/include/fileutils.h @@ -1,6 +1,20 @@ #ifndef UTIL_LINUX_FILEUTILS #define UTIL_LINUX_FILEUTILS -extern FILE * xmkstemp(char **tmpname); +extern int xmkstemp(char **tmpname); +static inline FILE *xfmkstemp(char **tmpname) +{ + int fd; + FILE *ret; + fd = xmkstemp(tmpname); + if (fd == -1) { + return NULL; + } + if (!(ret = fdopen(fd, "w+"))) { + close(fd); + return NULL; + } + return ret; +} #endif diff --git a/lib/fileutils.c b/lib/fileutils.c index 819298935..4849061bb 100644 --- a/lib/fileutils.c +++ b/lib/fileutils.c @@ -8,38 +8,35 @@ #include #include "c.h" +#include "fileutils.h" #include "pathnames.h" #include "xalloc.h" /* Create open temporary file in safe way. Please notice that the * file permissions are -rw------- by default. */ -FILE *xmkstemp(char **tmpname) +int xmkstemp(char **tmpname) { char *localtmp; char *tmpenv; mode_t old_mode; int fd; - FILE *ret; tmpenv = getenv("TMPDIR"); if (tmpenv) xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv, - program_invocation_short_name); + program_invocation_short_name); else xasprintf(&localtmp, "%s/%s.XXXXXX", _PATH_TMP, - program_invocation_short_name); + program_invocation_short_name); old_mode = umask(077); fd = mkstemp(localtmp); umask(old_mode); - if (fd == -1) - return NULL; - if (!(ret = fdopen(fd, "w+"))) - goto err; + if (fd == -1) { + free(localtmp); + localtmp = NULL; + } *tmpname = localtmp; - return ret; - err: - close(fd); - return NULL; + return fd; } #ifdef TEST_PROGRAM @@ -47,7 +44,7 @@ int main(void) { FILE *f; char *tmpname; - f = xmkstemp(&tmpname); + f = xfmkstemp(&tmpname); unlink(tmpname); free(tmpname); fclose(f); diff --git a/login-utils/setpwnam.c b/login-utils/setpwnam.c index 6f3f4920a..7459fe298 100644 --- a/login-utils/setpwnam.c +++ b/login-utils/setpwnam.c @@ -83,7 +83,7 @@ int setpwnam(struct passwd *pwd) pw_init(); - if ((fp = xmkstemp(&tmpname)) == NULL) + if ((fp = xfmkstemp(&tmpname)) == NULL) return -1; /* ptmp should be owned by root.root or root.wheel */ @@ -140,7 +140,7 @@ int setpwnam(struct passwd *pwd) fputs(linebuf, fp); } - /* xmkstemp is too restrictive by default for passwd file */ + /* xfmkstemp is too restrictive by default for passwd file */ if (fchmod(fileno(fp), 0644) < 0) goto fail; rc = fclose(fp); diff --git a/login-utils/vipw.c b/login-utils/vipw.c index 765d11120..29e485cc4 100644 --- a/login-utils/vipw.c +++ b/login-utils/vipw.c @@ -143,7 +143,7 @@ static FILE * pw_tmpfile(int lockfd) FILE *fd; char *tmpname = NULL; - if ((fd = xmkstemp(&tmpname)) == NULL) { + if ((fd = xfmkstemp(&tmpname)) == NULL) { ulckpwdf(); err(EXIT_FAILURE, _("can't open temporary file")); } diff --git a/term-utils/wall.c b/term-utils/wall.c index b9f53212a..fb3db2119 100644 --- a/term-utils/wall.c +++ b/term-utils/wall.c @@ -196,7 +196,7 @@ makemsg(char *fname, size_t *mbufsize, int print_banner) line_max = sysconf(_SC_LINE_MAX); lbuf = xmalloc(line_max); - if ((fp = xmkstemp(&tmpname)) == NULL) + if ((fp = xfmkstemp(&tmpname)) == NULL) err(EXIT_FAILURE, _("can't open temporary file")); unlink(tmpname); free(tmpname);