/* Read an image and check that file handles are being closed on minimise. * * This will only work on linux: we signal success and do nothing if /dev/proc * does not exist. */ #include #include #include /* Count the number of files in a directory, -1 for directory not found etc. */ static int count_files( const char *dirname ) { GDir *dir; int n; if( !(dir = g_dir_open( dirname, 0, NULL )) ) return( -1 ); for( n = 0; g_dir_read_name( dir ); n++ ) ; g_dir_close( dir ); return( n ); } int main( int argc, char **argv ) { VipsStreami *streami; VipsImage *image, *x; char fd_dir[256]; int n_files; double average; if( VIPS_INIT( argv[0] ) ) vips_error_exit( "unable to start" ); if( argc != 2 ) vips_error_exit( "usage: %s test-image", argv[0] ); vips_snprintf( fd_dir, 256, "/proc/%d/fd", getpid() ); n_files = count_files( fd_dir ); if( n_files == -1 ) /* Probably not linux, silent success. */ return( 0 ); /* This is usually 4. stdout / stdin / stderr plus one more made for * us by glib, I think, doing what I don't know. */ /* Opening an image should read the header, then close the fd. */ printf( "** seq open ..\n" ); if( !(streami = vips_streami_new_from_file( argv[1] )) ) vips_error_exit( NULL ); if( !(image = vips_image_new_from_stream( streami, "", "access", VIPS_ACCESS_SEQUENTIAL, NULL )) ) vips_error_exit( NULL ); if( count_files( fd_dir ) != n_files ) vips_error_exit( "%s: fd not closed after header read", argv[1] ); /* We should be able to read a chunk near the top, then have the fd * closed again. */ printf( "** crop1, avg ..\n" ); if( vips_crop( image, &x, 0, 0, image->Xsize, 10, NULL ) || vips_avg( x, &average, NULL ) ) vips_error_exit( NULL ); g_object_unref( x ); if( count_files( fd_dir ) != n_files ) vips_error_exit( "%s: fd not closed after first read", argv[1] ); /* We should be able to read again, a little further down, and have * the input restarted and closed again. */ printf( "** crop2, avg ..\n" ); if( vips_crop( image, &x, 0, 20, image->Xsize, 10, NULL ) || vips_avg( x, &average, NULL ) ) vips_error_exit( NULL ); g_object_unref( x ); if( count_files( fd_dir ) != n_files ) vips_error_exit( "%s: fd not closed after second read", argv[1] ); /* Clean up, and we should still just have three open. */ printf( "** unref ..\n" ); g_object_unref( image ); g_object_unref( streami ); printf( "** shutdown ..\n" ); vips_shutdown(); if( count_files( fd_dir ) != n_files ) vips_error_exit( "%s: fd not closed after shutdown", argv[1] ); return( 0 ); }