diff --git a/ChangeLog b/ChangeLog index 8d554b9d..d717a049 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,8 @@ - VipsStats tracks minpos/maxpos as well - moved mask/ to deprecated - use atexit() to call vips_shutdown() +- set _O_TEMPORARY on delete-on-close temp images if possible +- unlink temps on rewind on *nix, less likely to leave temps on a crash 12/10/11 started 7.26.6 - NOCACHE was not being set correctly on OS X causing performance diff --git a/TODO b/TODO index 6a0e96a9..7733e6cf 100644 --- a/TODO +++ b/TODO @@ -17,6 +17,9 @@ +- test _O_TEMPORARY thing on Windows + + - avg/dev etc. should uncode images? eg. labq2lab etc. diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 309fa63b..fd5ad2b9 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -167,6 +167,20 @@ static guint vips_image_signals[SIG_LAST] = { 0 }; G_DEFINE_TYPE( VipsImage, vips_image, VIPS_TYPE_OBJECT ); +static void +vips_image_delete( VipsImage *image ) +{ + if( image->delete_on_close ) { + g_assert( image->delete_on_close_filename ); + + VIPS_DEBUG_MSG( "vips_image_delete: removing temp %s\n", + image->delete_on_close_filename ); + g_unlink( image->delete_on_close_filename ); + VIPS_FREE( image->delete_on_close_filename ); + image->delete_on_close = FALSE; + } +} + static void vips_image_finalize( GObject *gobject ) { @@ -215,15 +229,9 @@ vips_image_finalize( GObject *gobject ) image->data = NULL; } - if( image->delete_on_close ) { - g_assert( image->delete_on_close_filename ); - - VIPS_DEBUG_MSG( "vips_image_finalize: removing temp %s\n", - image->delete_on_close_filename ); - g_unlink( image->delete_on_close_filename ); - VIPS_FREE( image->delete_on_close_filename ); - image->delete_on_close = FALSE; - } + /* If this is a temp, delete it. + */ + vips_image_delete( image ); VIPS_FREEF( g_mutex_free, image->sslock ); @@ -2003,6 +2011,19 @@ vips_image_rewind_output( VipsImage *image ) return( -1 ); } + /* Now we've finished writing and reopened as read, we can + * delete-on-close. + * + * On *nix-like systems, this will unlink the file + * from the filesystem and when we exit, for whatever reason, the file + * we be reclaimed. + * + * On Windows this will fail because the file is open and you can't + * delete open files. However, on Windows we set O_TEMP, so the file + * will be deleted anyway on exit. + */ + vips_image_delete( image ); + return( 0 ); } diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index ef145dc2..1603ccc4 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -952,9 +952,21 @@ vips_image_open_output( VipsImage *image ) * writing a VIPS image anyway. */ unsigned char header[VIPS_SIZEOF_HEADER]; + int flags; + + flags = MODE_WRITE; + + /* On Windows, setting O_TEMP gets the file automatically + * deleted on process exit, even if the processes crashes. See + * vips_image_rewind() for what we do to help on *nix. + */ +#ifdef _O_TEMPORARY + if( image->delete_on_close ) + flags |= _O_TEMPORARY; +#endif /*_O_TEMPORARY*/ if( (image->fd = vips_tracked_open( image->filename, - MODE_WRITE, 0666 )) < 0 ) { + flags, 0666 )) < 0 ) { vips_error_system( errno, "VipsImage", _( "unable to write to \"%s\"" ), image->filename );