Merge pull request #1034 'Implement os_mkdtemp on top of uv_fs_mkdtemp'

This commit is contained in:
Thiago de Arruda 2014-08-09 11:28:47 -03:00
commit 17e6000007
4 changed files with 32 additions and 36 deletions

View File

@ -566,11 +566,9 @@ attack or other people reading your file). When Vim exits the directory and
all files in it are deleted. When Vim has the setuid bit set this may cause all files in it are deleted. When Vim has the setuid bit set this may cause
problems, the temp file is owned by the setuid user but the filter command problems, the temp file is owned by the setuid user but the filter command
probably runs as the original user. probably runs as the original user.
On MS-DOS and OS/2 the first of these directories that works is used: $TMP, Directory for temporary files is created in the first suitable directory of:
$TEMP, c:\TMP, c:\TEMP. For Unix: $TMPDIR, /tmp, current-dir, $HOME.
For Unix the list of directories is: $TMPDIR, /tmp, current-dir, $HOME. For MS-Windows: $TMP, $TEMP, $USERPROFILE, current-dir.
For MS-Windows the GetTempFileName() system function is used.
For other systems the tmpnam() library function is used.

View File

@ -6212,8 +6212,7 @@ taglist({expr}) *taglist()*
tempname() *tempname()* *temp-file-name* tempname() *tempname()* *temp-file-name*
The result is a String, which is the name of a file that The result is a String, which is the name of a file that
doesn't exist. It can be used for a temporary file. The name doesn't exist. It can be used for a temporary file. Example: >
is different for at least 26 consecutive calls. Example: >
:let tmpfile = tempname() :let tmpfile = tempname()
:exe "redir > " . tmpfile :exe "redir > " . tmpfile
< For Unix, the file will be in a private directory |tempfile|. < For Unix, the file will be in a private directory |tempfile|.

View File

@ -3,13 +3,6 @@
#include <assert.h> #include <assert.h>
// TODO(hinidu): remove after implementing `os_mkdtemp` on top of libuv
#ifdef WIN32
# include <io.h>
#else
# include <stdlib.h>
#endif
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/ascii.h" #include "nvim/ascii.h"
#include "nvim/memory.h" #include "nvim/memory.h"
@ -293,18 +286,21 @@ int os_mkdir(const char *path, int32_t mode)
} }
/// Create a unique temporary directory. /// Create a unique temporary directory.
/// TODO(hinidu): Implement on top of libuv. ref #850
/// ///
/// @param[in,out] template Template of the path to the directory with XXXXXX /// @param[in] template Template of the path to the directory with XXXXXX
/// which would be replaced by random chars. /// which would be replaced by random chars.
/// @return Pointer to changed `template` for success, `NULL` for failure. /// @param[out] path Path to created directory for success, undefined for
char *os_mkdtemp(char *template) /// failure.
/// @return `0` for success, non-zero for failure.
int os_mkdtemp(const char *template, char *path)
{ {
#ifdef WIN32 uv_fs_t request;
return _mktemp(template) && os_mkdir(template, 0700) == 0 ? template : NULL; int result = uv_fs_mkdtemp(uv_default_loop(), &request, template, NULL);
#else if (result == kLibuvSuccess) {
return mkdtemp(template); strcpy(path, request.path);
#endif }
uv_fs_req_cleanup(&request);
return result;
} }
/// Remove a directory. /// Remove a directory.

View File

@ -28,26 +28,29 @@ static void vim_maketempdir(void)
{ {
static const char *temp_dirs[] = TEMP_DIR_NAMES; static const char *temp_dirs[] = TEMP_DIR_NAMES;
// Try the entries in `TEMP_DIR_NAMES` to create the temp directory. // Try the entries in `TEMP_DIR_NAMES` to create the temp directory.
char_u itmp[TEMP_FILE_PATH_MAXLEN]; char_u template[TEMP_FILE_PATH_MAXLEN];
char_u path[TEMP_FILE_PATH_MAXLEN];
for (size_t i = 0; i < sizeof(temp_dirs) / sizeof(char *); ++i) { for (size_t i = 0; i < sizeof(temp_dirs) / sizeof(char *); ++i) {
// Expand environment variables, leave room for "/nvimXXXXXX/999999999" // Expand environment variables, leave room for "/nvimXXXXXX/999999999"
expand_env((char_u *)temp_dirs[i], itmp, TEMP_FILE_PATH_MAXLEN - 22); expand_env((char_u *)temp_dirs[i], template, TEMP_FILE_PATH_MAXLEN - 22);
if (!os_isdir(itmp)) { // directory doesn't exist if (!os_isdir(template)) { // directory doesn't exist
continue; continue;
} }
add_pathsep(itmp); add_pathsep(template);
// Concatenate with temporary directory name pattern // Concatenate with temporary directory name pattern
STRCAT(itmp, "nvimXXXXXX"); STRCAT(template, "nvimXXXXXX");
if (!os_mkdtemp((char *)itmp)) {
if (os_mkdtemp((const char *)template, (char *)path) != 0) {
continue; continue;
} }
if (vim_settempdir(itmp)) {
if (vim_settempdir(path)) {
// Successfully created and set temporary directory so stop trying. // Successfully created and set temporary directory so stop trying.
break; break;
} else { } else {
// Couldn't set `vim_tempdir` to itmp so remove created directory. // Couldn't set `vim_tempdir` to `path` so remove created directory.
os_rmdir((char *)itmp); os_rmdir((char *)path);
} }
} }
} }
@ -128,8 +131,8 @@ char_u *vim_tempname(void)
// There is no need to check if the file exists, because we own the directory // There is no need to check if the file exists, because we own the directory
// and nobody else creates a file in it. // and nobody else creates a file in it.
char_u itmp[TEMP_FILE_PATH_MAXLEN]; char_u template[TEMP_FILE_PATH_MAXLEN];
snprintf((char *)itmp, TEMP_FILE_PATH_MAXLEN, snprintf((char *)template, TEMP_FILE_PATH_MAXLEN,
"%s%" PRIu32, tempdir, temp_count++); "%s%" PRIu32, tempdir, temp_count++);
return vim_strsave(itmp); return vim_strsave(template);
} }