From e73691e1a47834aff367c9131fc3c7d78751d821 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 18 Aug 2017 20:36:10 -0700 Subject: [PATCH] Improve make-temp-file performance on local files * lisp/files.el (make-temp-file): Let make-temp-file-internal do the work of inserting the text. * src/fileio.c (Fmake_temp_file_internal): New arg TEXT. All callers changed. --- lisp/files.el | 20 ++++++++------------ src/fileio.c | 22 ++++++++++++++++------ src/filelock.c | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/lisp/files.el b/lisp/files.el index a2b474f8d2b..0311cc6d210 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1404,24 +1404,20 @@ of PREFIX, and expanding against `temporary-file-directory' if necessary), is guaranteed to point to a newly created file. You can then use `write-region' to write new data into the file. -If TEXT is non-nil, it will be inserted in the new file. Otherwise -the file will be empty. - If DIR-FLAG is non-nil, create a new empty directory instead of a file. -If SUFFIX is non-nil, add that at the end of the file name." +If SUFFIX is non-nil, add that at the end of the file name. + +If TEXT is a string, insert it into the new file; DIR-FLAG should be nil. +Otherwise the file will be empty." (let ((absolute-prefix (if (or (zerop (length prefix)) (member prefix '("." ".."))) (concat (file-name-as-directory temporary-file-directory) prefix) - (expand-file-name prefix temporary-file-directory))) - (contents (if (stringp text) text ""))) + (expand-file-name prefix temporary-file-directory)))) (if (find-file-name-handler absolute-prefix 'write-region) - (files--make-magic-temp-file absolute-prefix dir-flag suffix contents) - (let ((file (make-temp-file-internal absolute-prefix - (if dir-flag t) (or suffix "")))) - (when (and (stringp text) (not dir-flag)) - (write-region contents nil file nil 'silent)) - file)))) + (files--make-magic-temp-file absolute-prefix dir-flag suffix text) + (make-temp-file-internal absolute-prefix + (if dir-flag t) (or suffix "") text)))) (defun files--make-magic-temp-file (absolute-prefix &optional dir-flag suffix text) diff --git a/src/fileio.c b/src/fileio.c index 1b832be344d..6b3bdf2154d 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -657,18 +657,20 @@ In Unix-syntax, this function just removes the final slash. */) } DEFUN ("make-temp-file-internal", Fmake_temp_file_internal, - Smake_temp_file_internal, 3, 3, 0, + Smake_temp_file_internal, 4, 4, 0, doc: /* Generate a new file whose name starts with PREFIX, a string. Return the name of the generated file. If DIR-FLAG is zero, do not create the file, just its name. Otherwise, if DIR-FLAG is non-nil, create an empty directory. The file name should end in SUFFIX. Do not expand PREFIX; a non-absolute PREFIX is relative to the Emacs -working directory. +working directory. If TEXT is a string, insert it into the newly +created file. Signal an error if the file could not be created. This function does not grok magic file names. */) - (Lisp_Object prefix, Lisp_Object dir_flag, Lisp_Object suffix) + (Lisp_Object prefix, Lisp_Object dir_flag, Lisp_Object suffix, + Lisp_Object text) { CHECK_STRING (prefix); CHECK_STRING (suffix); @@ -688,7 +690,15 @@ This function does not grok magic file names. */) : EQ (dir_flag, make_number (0)) ? GT_NOCREATE : GT_DIR); int fd = gen_tempname (data, suffix_len, O_BINARY | O_CLOEXEC, kind); - if (fd < 0 || (NILP (dir_flag) && emacs_close (fd) != 0)) + bool failed = fd < 0; + if (!failed) + { + val = DECODE_FILE (val); + if (STRINGP (text) && SBYTES (text) != 0) + write_region (text, Qnil, val, Qnil, Qnil, Qnil, Qnil, fd); + failed = NILP (dir_flag) && emacs_close (fd) != 0; + } + if (failed) { static char const kind_message[][32] = { @@ -698,7 +708,7 @@ This function does not grok magic file names. */) }; report_file_error (kind_message[kind], prefix); } - return DECODE_FILE (val); + return val; } @@ -715,7 +725,7 @@ For that reason, you should normally use `make-temp-file' instead. */) (Lisp_Object prefix) { return Fmake_temp_file_internal (prefix, make_number (0), - empty_unibyte_string); + empty_unibyte_string, Qnil); } DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, diff --git a/src/filelock.c b/src/filelock.c index fec9bc044ae..fd4f0aa864e 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -210,7 +210,7 @@ get_boot_time (void) names up to 8 bytes long. Choose a 2 byte prefix, so the 6-byte suffix does not make the name too long. */ filename = Fmake_temp_file_internal (build_string ("wt"), Qnil, - empty_unibyte_string); + empty_unibyte_string, Qnil); CALLN (Fcall_process, build_string ("gzip"), Qnil, list2 (QCfile, filename), Qnil, build_string ("-cd"), tempname); -- 2.39.2