better temp filename handling

- make access() fail only if we are certain the file does not exist
- remove the g_mkstemp() from vips__temp_name()

should help selinux

see https://github.com/jcupitt/libvips/pull/930
This commit is contained in:
John Cupitt 2018-04-26 16:12:01 +01:00
parent 9714dcdee3
commit 6952c57ca0
1 changed files with 20 additions and 17 deletions

View File

@ -1118,9 +1118,9 @@ vips__ftruncate( int fd, gint64 pos )
return( 0 ); return( 0 );
} }
/* Test for file exists. /* TRUE if file exists.
*/ */
int gboolean
vips_existsf( const char *name, ... ) vips_existsf( const char *name, ... )
{ {
va_list ap; va_list ap;
@ -1135,7 +1135,12 @@ vips_existsf( const char *name, ... )
g_free( path ); g_free( path );
return( !result ); /* access() can fail for various reasons, especially under things
* like selinux. Only return FALSE if we are certain the file does not
* exist.
*/
return( result == 0 ||
errno != ENOENT );
} }
#ifdef OS_WIN32 #ifdef OS_WIN32
@ -1624,32 +1629,30 @@ vips__temp_dir( void )
/* Make a temporary file name. The format parameter is something like "%s.jpg" /* Make a temporary file name. The format parameter is something like "%s.jpg"
* and will be expanded to something like "/tmp/vips-12-34587.jpg". * and will be expanded to something like "/tmp/vips-12-34587.jpg".
* *
* You need to free the result. A real file will also be created, though we * You need to free the result.
* delete it for you.
*/ */
char * char *
vips__temp_name( const char *format ) vips__temp_name( const char *format )
{ {
static int serial = 1; static int serial = 0;
char file[FILENAME_MAX]; char file[FILENAME_MAX];
char file2[FILENAME_MAX]; char file2[FILENAME_MAX];
char *name; char *name;
int fd;
vips_snprintf( file, FILENAME_MAX, "vips-%d-XXXXXX", serial++ ); vips_snprintf( file, FILENAME_MAX, "vips-%d-%u",
serial++, g_random_int() );
vips_snprintf( file2, FILENAME_MAX, format, file ); vips_snprintf( file2, FILENAME_MAX, format, file );
name = g_build_filename( vips__temp_dir(), file2, NULL ); name = g_build_filename( vips__temp_dir(), file2, NULL );
if( (fd = g_mkstemp( name )) == -1 ) { /* We could use something like g_mkstemp() to guarantee uniqueness
vips_error( "tempfile", * across processes, but the extra FS calls can be difficult for
_( "unable to make temporary file %s" ), name ); * selinux.
g_free( name ); *
return( NULL ); * g_random_int() should be safe enough -- it's seeded from time(), so
} * it ought not to collide often -- and on linux at least we never
close( fd ); * actually use these filenames in the filesystem anyway.
g_unlink( name ); */
return( name ); return( name );
} }