diff --git a/client/mysql.cc b/client/mysql.cc index 9569ff6196f..6a720c38ef1 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4205,8 +4205,7 @@ com_edit(String *buffer,char *line __attribute__((unused))) const char *editor; MY_STAT stat_arg; - if ((fd=create_temp_file(filename,NullS,"sql", O_CREAT | O_WRONLY, - MYF(MY_WME))) < 0) + if ((fd= create_temp_file(filename,NullS,"sql", 0, MYF(MY_WME))) < 0) goto err; if (buffer->is_empty() && !old_buffer.is_empty()) (void) my_write(fd,(uchar*) old_buffer.ptr(),old_buffer.length(), diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c index d297f3cd03e..40560613a89 100644 --- a/client/mysql_plugin.c +++ b/client/mysql_plugin.c @@ -159,8 +159,7 @@ static int make_tempfile(char *filename, const char *ext) { int fd= 0; - if ((fd=create_temp_file(filename, NullS, ext, O_CREAT | O_WRONLY, - MYF(MY_WME))) < 0) + if ((fd= create_temp_file(filename, NullS, ext, 0, MYF(MY_WME))) < 0) { fprintf(stderr, "ERROR: Cannot generate temporary file. Error code: %d.\n", fd); diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 64e0c68a9ce..ef1630dd0e3 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -558,8 +558,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res, DBUG_PRINT("enter", ("query: %s", query)); if ((fd= create_temp_file(query_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL, - "sql", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) + "sql", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for defaults"); /* @@ -1176,7 +1175,7 @@ int main(int argc, char **argv) cnf_file_path= strmov(defaults_file, "--defaults-file="); { int fd= create_temp_file(cnf_file_path, opt_tmpdir[0] ? opt_tmpdir : NULL, - "mysql_upgrade-", O_CREAT | O_WRONLY, MYF(MY_FAE)); + "mysql_upgrade-", 0, MYF(MY_FAE)); if (fd < 0) die(NULL); my_write(fd, USTRING_WITH_LEN( "[client]\n"), MYF(MY_FAE)); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 491ec078e3d..f26ea994a4c 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -2209,8 +2209,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) DBUG_ENTER("dyn_string_cmp"); DBUG_PRINT("enter", ("fname: %s", fname)); - if ((fd= create_temp_file(temp_file_path, TMPDIR, - "tmp", O_CREAT | O_SHARE | O_RDWR, + if ((fd= create_temp_file(temp_file_path, TMPDIR, "tmp", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for ds"); @@ -4684,8 +4683,7 @@ void do_perl(struct st_command *command) /* Create temporary file name */ if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"), - "tmp", O_CREAT | O_SHARE | O_RDWR, - MYF(MY_WME))) < 0) + "tmp", O_SHARE, MYF(MY_WME))) < 0) die("Failed to create temporary file for perl command"); my_close(fd, MYF(0)); diff --git a/extra/mariabackup/ds_tmpfile.c b/extra/mariabackup/ds_tmpfile.c index 443b3703b20..0e5decc5a6e 100644 --- a/extra/mariabackup/ds_tmpfile.c +++ b/extra/mariabackup/ds_tmpfile.c @@ -91,22 +91,8 @@ tmpfile_open(ds_ctxt_t *ctxt, const char *path, /* Create a temporary file in tmpdir. The file will be automatically removed on close. Code copied from mysql_tmpfile(). */ fd = create_temp_file(tmp_path,xtrabackup_tmpdir, - "xbtemp", -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_TEMPORARY | O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR, - MYF(MY_WME)); - -#ifndef __WIN__ - if (fd >= 0) { - /* On Windows, open files cannot be removed, but files can be - created with the O_TEMPORARY flag to the same effect - ("delete on close"). */ - unlink(tmp_path); - } -#endif /* !__WIN__ */ + "xbtemp", O_BINARY | O_SEQUENTIAL, + MYF(MY_WME | MY_TEMPORARY)); if (fd < 0) { return NULL; diff --git a/extra/replace.c b/extra/replace.c index eabf953837b..4086f22d129 100644 --- a/extra/replace.c +++ b/extra/replace.c @@ -1072,7 +1072,7 @@ static int convert_file(REPLACE *rep, char * name) if (!(in= my_fopen(org_name,O_RDONLY,MYF(MY_WME)))) DBUG_RETURN(1); dirname_part(dir_buff, org_name, &dir_buff_length); - if ((temp_file= create_temp_file(tempname, dir_buff, "PR", O_WRONLY, + if ((temp_file= create_temp_file(tempname, dir_buff, "PR", 0, MYF(MY_WME))) < 0) { my_fclose(in,MYF(0)); diff --git a/include/my_global.h b/include/my_global.h index 9982f6339e4..0769feca94a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -600,8 +600,8 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif #endif /* O_SHARE */ -#ifndef O_TEMPORARY -#define O_TEMPORARY 0 +#ifndef O_SEQUENTIAL +#define O_SEQUENTIAL 0 #endif #ifndef O_SHORT_LIVED #define O_SHORT_LIVED 0 diff --git a/include/my_sys.h b/include/my_sys.h index 1a9d738a5f9..c64147c5e68 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -67,6 +67,7 @@ typedef struct my_aio_result { #define MY_WAIT_IF_FULL 32U /* Wait and try again if disk full error */ #define MY_IGNORE_BADFD 32U /* my_sync(): ignore 'bad descriptor' errors */ #define MY_ENCRYPT 64U /* Encrypt IO_CACHE temporary files */ +#define MY_TEMPORARY 64U /* create_temp_file(): delete file at once */ #define MY_NOSYMLINKS 512U /* my_open(): don't follow symlinks */ #define MY_FULL_IO 512U /* my_read(): loop until I/O is complete */ #define MY_DONT_CHECK_FILESIZE 128U /* Option to init_io_cache() */ diff --git a/mysys/mf_cache.c b/mysys/mf_cache.c index a3426889a82..478900ddb2a 100644 --- a/mysys/mf_cache.c +++ b/mysys/mf_cache.c @@ -20,36 +20,6 @@ #include "my_static.h" #include "mysys_err.h" -/** - Remove an open tempfile so that it doesn't survive if we crash - - If the operating system doesn't support this, just remember - the file name for later removal -*/ - -static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)), - const char *name) -{ -#if O_TEMPORARY == 0 -#if !defined(CANT_DELETE_OPEN_FILES) - /* The following should always succeed */ - (void) my_delete(name,MYF(MY_WME | ME_NOINPUT)); -#else - int length; - if (!(cache->file_name= - (char*) my_malloc((length=strlen(name)+1),MYF(MY_WME)))) - { - my_close(cache->file,MYF(0)); - cache->file = -1; - errno=my_errno=ENOMEM; - return 1; - } - memcpy(cache->file_name,name,length); -#endif -#endif /* O_TEMPORARY == 0 */ - return 0; -} - /** Open tempfile cached by IO_CACHE @@ -88,14 +58,11 @@ my_bool real_open_cached_file(IO_CACHE *cache) char name_buff[FN_REFLEN]; int error=1; DBUG_ENTER("real_open_cached_file"); - if ((cache->file=create_temp_file(name_buff, cache->dir, + if ((cache->file= create_temp_file(name_buff, cache->dir, cache->prefix[0] ? cache->prefix : 0, - (O_RDWR | O_BINARY | O_TRUNC | - O_TEMPORARY | O_SHORT_LIVED), - MYF(MY_WME))) >= 0) + O_BINARY, MYF(MY_WME | MY_TEMPORARY))) >= 0) { error=0; - cache_remove_open_tmp(cache, name_buff); } DBUG_RETURN(error); } diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index c114180c101..40787c77295 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -45,8 +45,11 @@ implementation, it's main use is to generate a file with a name that does not already exist. - When passing O_TEMPORARY flag in "mode" the file should - be automatically deleted + When passing MY_TEMPORARY flag in MyFlags the file is automatically deleted + + "mode" bits that always must be used for newly created files with + unique file names (O_EXCL | O_TRUNC | O_CREAT | O_RDWR) are added + automatically, and shouldn't be specified by the caller. The implementation using mkstemp should be considered the reference implementation when adding a new or modifying an @@ -55,51 +58,55 @@ */ File create_temp_file(char *to, const char *dir, const char *prefix, - int mode __attribute__((unused)), - myf MyFlags __attribute__((unused))) + int mode, myf MyFlags) { File file= -1; -#ifdef __WIN__ - TCHAR path_buf[MAX_PATH-14]; -#endif DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); -#if defined (__WIN__) + DBUG_ASSERT((mode & (O_EXCL | O_TRUNC | O_CREAT | O_RDWR)) == 0); - /* - Use GetTempPath to determine path for temporary files. - This is because the documentation for GetTempFileName - has the following to say about this parameter: - "If this parameter is NULL, the function fails." - */ - if (!dir) - { - if(GetTempPath(sizeof(path_buf), path_buf) > 0) - dir = path_buf; - } - /* - Use GetTempFileName to generate a unique filename, create - the file and release it's handle - - uses up to the first three letters from prefix - */ - if (GetTempFileName(dir, prefix, 0, to) == 0) - DBUG_RETURN(-1); + mode|= O_TRUNC | O_CREAT | O_RDWR; /* not O_EXCL, see Windows code below */ - DBUG_PRINT("info", ("name: %s", to)); - - /* - Open the file without the "open only if file doesn't already exist" - since the file has already been created by GetTempFileName - */ - if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0) +#ifdef _WIN32 { - /* Open failed, remove the file created by GetTempFileName */ - int tmp= my_errno; - (void) my_delete(to, MYF(0)); - my_errno= tmp; - } + TCHAR path_buf[MAX_PATH-14]; + /* + Use GetTempPath to determine path for temporary files. + This is because the documentation for GetTempFileName + has the following to say about this parameter: + "If this parameter is NULL, the function fails." + */ + if (!dir) + { + if(GetTempPath(sizeof(path_buf), path_buf) > 0) + dir = path_buf; + } + /* + Use GetTempFileName to generate a unique filename, create + the file and release it's handle + - uses up to the first three letters from prefix + */ + if (GetTempFileName(dir, prefix, 0, to) == 0) + DBUG_RETURN(-1); + DBUG_PRINT("info", ("name: %s", to)); + + if (MyFlags & MY_TEMPORARY) + mode|= O_SHORT_LIVED | O_TEMPORARY; + + /* + Open the file without O_EXCL flag + since the file has already been created by GetTempFileName + */ + if ((file= my_open(to, mode, MyFlags)) < 0) + { + /* Open failed, remove the file created by GetTempFileName */ + int tmp= my_errno; + (void) my_delete(to, MYF(0)); + my_errno= tmp; + } + } #elif defined(HAVE_MKSTEMP) { char prefix_buff[30]; @@ -119,8 +126,8 @@ File create_temp_file(char *to, const char *dir, const char *prefix, } strmov(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); - if (mode & O_TEMPORARY) - (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); + if (org_file >= 0 && (MyFlags & MY_TEMPORARY)) + (void) my_delete(to, MYF(MY_WME)); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 92795a8f797..b58ed52db31 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -336,24 +336,9 @@ ulong get_max_connections(void) extern "C" int mysql_tmpfile(const char *prefix) { char filename[FN_REFLEN]; - File fd = create_temp_file(filename, mysql_tmpdir, prefix, -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY, - MYF(MY_WME)); - if (fd >= 0) { -#ifndef __WIN__ - /* - This can be removed once the following bug is fixed: - Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option - (file not removed) (Unix) - */ - unlink(filename); -#endif /* !__WIN__ */ - } - + File fd= create_temp_file(filename, mysql_tmpdir, prefix, + O_BINARY | O_SEQUENTIAL, + MYF(MY_WME | MY_TEMPORARY)); return fd; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 059718b45f6..0e613edd196 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2385,24 +2385,8 @@ static int mysql_tmpfile_path(const char *path, const char *prefix) DBUG_ASSERT((strlen(path) + strlen(prefix)) <= FN_REFLEN); char filename[FN_REFLEN]; - File fd = create_temp_file(filename, path, prefix, -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR | O_TEMPORARY, - MYF(MY_WME)); - if (fd >= 0) { -#ifndef __WIN__ - /* - This can be removed once the following bug is fixed: - Bug #28903 create_temp_file() doesn't honor O_TEMPORARY option - (file not removed) (Unix) - */ - unlink(filename); -#endif /* !__WIN__ */ - } - + File fd = create_temp_file(filename, path, prefix, O_BINARY | O_SEQUENTIAL, + MYF(MY_WME | MY_TEMPORARY)); return fd; }