diff --git a/ChangeLog b/ChangeLog index 8ecf5d36..62a8e74a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ 23/9/18 started 8.7.1 - update function list in docs [janko-m] - test for g_str_to_ascii() [jcupitt] +- fix temp file open on Windows and fallback on linux [lovell] 23/12/17 started 8.7.0 - add magicksave, save image with libMagick [dlemstra] diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index e4489778..99893a11 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -3077,13 +3077,13 @@ vips_image_rewind_output( VipsImage *image ) /* 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 + * 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 when the fd is finally closed. + * delete open files. However, on Windows we set _O_TEMPORARY, so the + * file will be deleted when the fd is finally closed. */ vips_image_delete( image ); diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 7cabaff0..e7d71378 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -137,7 +137,6 @@ * * We use O_RDWR not O_WRONLY since after writing we may want to rewind the * image and read from it. - * */ #define MODE_WRITE BINARYIZE (O_RDWR | O_CREAT | O_TRUNC) @@ -187,37 +186,37 @@ vips__open_image_write( const char *filename, gboolean temp ) int flags; int fd; - flags = MODE_WRITE; + fd = -1; #ifdef O_TMPFILE /* Linux-only extension creates an unlinked file. CREAT and TRUNC must * be clear. The filename arg to open() must name a directory. + * + * This can fail since not all filesystems support it. In this case, + * we open as a regular file and rely on the delete-on-close + * mechanism, see vips_image_delete(). */ if( temp ) { char *dirname; - flags |= O_TMPFILE; - flags &= ~O_CREAT; - flags &= ~O_TRUNC; - dirname = g_path_get_dirname( filename ); - fd = vips_tracked_open( dirname, flags, 0666 ); + fd = vips_tracked_open( dirname, O_TMPFILE | O_RDWR , 0666 ); g_free( dirname ); } - else - fd = vips_tracked_open( filename, flags, 0666 ); -#else /*!O_TMPFILE*/ - fd = vips_tracked_open( filename, flags, 0666 ); +#endif /*O_TMPFILE*/ + + flags = MODE_WRITE; #ifdef _O_TEMPORARY - /* On Windows, setting _O_TEMPORARY 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. + /* On Windows, setting _O_TEMPORARY will delete the file automatically + * on process exit, even if the processes crashes. */ if( temp ) flags |= _O_TEMPORARY; #endif /*_O_TEMPORARY*/ -#endif /*O_TMPFILE*/ + + if( fd < 0 ) + fd = vips_tracked_open( filename, flags, 0666 ); if( fd < 0 ) { vips_error_system( errno, "VipsImage",