From: Lars Kellogg-Stedman Date: Tue, 15 May 2018 16:43:35 +0000 (-0400) Subject: Partial solution to #1165 (#1176) X-Git-Tag: neomutt-20180622~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3539616c1cc9c8cec30b259d19898f3e938f6d52;p=neomutt Partial solution to #1165 (#1176) * mutt/file.c: allow mutt_file_mkstemp to return a filename modify mutt_file_mkstemp so that a caller may pass in a character buffer that will be filled with the temporary filename. When a non-null buffer is provided, mutt_file_mkstemp will *not* unlink the temporary file and will leave cleanup to the caller. Closes: #1165 --- diff --git a/attach.c b/attach.c index 186e1e01d..db6a693fa 100644 --- a/attach.c +++ b/attach.c @@ -176,8 +176,7 @@ int mutt_compose_attachment(struct Body *a) * copying the file back */ fseeko(fp, b->offset, SEEK_SET); mutt_body_free(&b); - mutt_mktemp(tempfile, sizeof(tempfile)); - FILE *tfp = mutt_file_fopen(tempfile, "w"); + FILE *tfp = mutt_file_mkstemp_name(tempfile, sizeof(tempfile)); if (!tfp) { mutt_perror(_("Failure to open file to strip headers.")); diff --git a/editmsg.c b/editmsg.c index c98025a08..b7ec2a428 100644 --- a/editmsg.c +++ b/editmsg.c @@ -73,11 +73,13 @@ static int edit_or_view_one_message(bool edit, struct Context *ctx, struct Heade struct Message *msg = NULL; FILE *fp = NULL; + FILE *tfp = NULL; struct stat sb; time_t mtime = 0; - mutt_mktemp(tmp, sizeof(tmp)); + tfp = mutt_file_mkstemp_name(tmp, sizeof(tmp)); + mutt_file_mkstemp_finish(tfp, tmp); omagic = MboxType; MboxType = MUTT_MBOX; diff --git a/mutt/file.c b/mutt/file.c index 1cf3f91e7..e47c72805 100644 --- a/mutt/file.c +++ b/mutt/file.c @@ -861,11 +861,17 @@ int mutt_file_mkdir(const char *path, mode_t mode) * * Create and immediately unlink a temp file using mkstemp(). */ -FILE *mutt_file_mkstemp_full(const char *file, int line, const char *func) +FILE *mutt_file_mkstemp_full(char *name, size_t namelen, + const char *file, int line, const char *func) { - char name[PATH_MAX]; + char noname[PATH_MAX]; - int n = snprintf(name, sizeof(name), "%s/neomutt-XXXXXX", NONULL(Tmpdir)); + if (name == NULL) { + name = noname; + namelen = PATH_MAX; + } + + int n = snprintf(name, namelen, "%s/neomutt-XXXXXX", NONULL(Tmpdir)); if (n < 0) return NULL; @@ -874,17 +880,27 @@ FILE *mutt_file_mkstemp_full(const char *file, int line, const char *func) return NULL; FILE *fp = fdopen(fd, "w+"); + MuttLogger(0, file, line, func, 1, "created temp file '%s'\n", name); - if ((unlink(name) != 0) && (errno != ENOENT)) - { - mutt_file_fclose(&fp); - return NULL; + if (name == noname) { + if ((unlink(name) != 0) && (errno != ENOENT)) + return NULL; + + MuttLogger(0, file, line, func, 1, "unlinked temp file '%s'\n", name); } - MuttLogger(0, file, line, func, 1, "created temp file '%s'\n", name); return fp; } +int mutt_file_mkstemp_finish(FILE *fp, const char *name) { + if (name != NULL) { + if (unlink(name) && (errno != ENOENT)) + return -1; + } + + return mutt_file_fclose(&fp); +} + /** * mutt_file_decrease_mtime - Decrease a file's modification time by 1 second * @param f Filename diff --git a/mutt/file.h b/mutt/file.h index ad1ed571a..e73ba2f25 100644 --- a/mutt/file.h +++ b/mutt/file.h @@ -52,8 +52,10 @@ FILE * mutt_file_fopen(const char *path, const char *mode); int mutt_file_fsync_close(FILE **f); int mutt_file_lock(int fd, int excl, int timeout); int mutt_file_mkdir(const char *path, mode_t mode); -FILE * mutt_file_mkstemp_full(const char *file, int line, const char *func); -#define mutt_file_mkstemp() mutt_file_mkstemp_full(__FILE__, __LINE__, __func__) +FILE * mutt_file_mkstemp_full(char *name, size_t namelen, const char *file, int line, const char *func); +#define mutt_file_mkstemp() mutt_file_mkstemp_full(NULL, 0, __FILE__, __LINE__, __func__) +#define mutt_file_mkstemp_name(name, namelen) mutt_file_mkstemp_full(name, namelen, __FILE__, __LINE__, __func__) +int mutt_file_mkstemp_finish(FILE *, const char *); int mutt_file_open(const char *path, int flags); size_t mutt_file_quote_filename(char *d, size_t l, const char *f); char * mutt_file_read_keyword(const char *file, char *buffer, size_t buflen);