@@ -26,30 +26,32 @@ int git_futils_mkpath2file(const char *file_path, const mode_t mode)
2626
2727int git_futils_mktmp (git_str * path_out , const char * filename , mode_t mode )
2828{
29+ const int open_flags = O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_CLOEXEC ;
30+ /* TMP_MAX is unrelated to mktemp but should provide a reasonable amount */
31+ unsigned int tries = TMP_MAX ;
2932 int fd ;
30- mode_t mask ;
3133
32- p_umask (mask = p_umask (0 ));
34+ while (tries -- ) {
35+ git_str_sets (path_out , filename );
36+ git_str_puts (path_out , "_git2_XXXXXX" );
3337
34- git_str_sets (path_out , filename );
35- git_str_puts (path_out , "_git2_XXXXXX" );
36-
37- if (git_str_oom (path_out ))
38- return -1 ;
38+ if (git_str_oom (path_out ))
39+ return -1 ;
3940
40- if (( fd = p_mkstemp ( path_out -> ptr )) < 0 ) {
41- git_error_set ( GIT_ERROR_OS ,
42- "failed to create temporary file '%s'" , path_out -> ptr );
43- return -1 ;
44- }
41+ /* Using mktemp is safe when we open with O_CREAT | O_EXCL */
42+ p_mktemp ( path_out -> ptr );
43+ /* mktemp sets template to empty string on failure */
44+ if ( path_out -> ptr [ 0 ] == '\0' )
45+ break ;
4546
46- if (p_chmod (path_out -> ptr , (mode & ~mask ))) {
47- git_error_set (GIT_ERROR_OS ,
48- "failed to set permissions on file '%s'" , path_out -> ptr );
49- return -1 ;
47+ if ((fd = p_open (path_out -> ptr , open_flags , mode )) >= 0 )
48+ return fd ;
5049 }
5150
52- return fd ;
51+ git_error_set (GIT_ERROR_OS ,
52+ "failed to create temporary file '%s'" , path_out -> ptr );
53+ git_str_dispose (path_out );
54+ return -1 ;
5355}
5456
5557int git_futils_creat_withpath (const char * path , const mode_t dirmode , const mode_t mode )
0 commit comments