libvips/test/test_descriptors.c

164 lines
3.7 KiB
C
Raw Normal View History

/* 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
* /proc/self/fd does not exist.
*/
#include <stdio.h>
#include <unistd.h>
#define _GNU_SOURCE
#include <stdlib.h>
#include <vips/vips.h>
/**
* get_open_files:
*
* Get a list of open files for this process.
*
* Returns (transfer full) (nullable): a new #GSList, or %NULL
*/
static GSList *
get_open_files()
{
GSList *list = NULL;
GDir *dir;
const char *name;
if( !(dir = g_dir_open( "/proc/self/fd", 0, NULL )) )
return( NULL );
while( (name = g_dir_read_name( dir )) ) {
char *fullname = g_build_filename( "/proc/self/fd", name, NULL );
list = g_slist_prepend( list, realpath( fullname, NULL ) );
g_free( fullname );
}
g_dir_close( dir );
return( list );
}
/**
* fd_check:
* @stage: the originating stage for the error message
* @fds: a #GSList of file descriptors to check against
*
* Check for a leak by comparing the currently open files for this
* process with the file descriptors in @fds. If there's a leak,
* print an error message and return %FALSE.
*
* See also: get_open_files().
*
* Returns: %TRUE if there are no leaks; %FALSE otherwise
*/
static gboolean
fd_check( const char *stage, GSList *fds )
{
GSList *unique_list = NULL, *list, *iter;
list = get_open_files();
for( iter = list; iter; iter = iter->next )
if( !g_slist_find_custom( fds, iter->data,
(GCompareFunc) g_strcmp0 ) )
unique_list = g_slist_prepend( unique_list, iter->data );
if( unique_list == NULL ) {
g_slist_free_full( list, g_free );
return( TRUE );
}
fprintf( stderr, "%s: file descriptors not closed after %s:\n",
vips_get_prgname(), stage );
for( iter = unique_list; iter; iter = iter->next )
fprintf( stderr, "%s\n", (char *) iter->data );
g_slist_free( unique_list );
g_slist_free_full( list, g_free );
return( FALSE );
}
int
main( int argc, char **argv )
{
experiment with renaming stream rename as VipsConnection, VipsSource, VipsTarget etc. see https://github.com/libvips/libvips/issues/1494#issuecomment-569498619 renamed with this script: ``` set -e edit() { sed -i -E "$1" rename } for i in $*; do cp $i rename edit s/VIPS_STREAMOU/VIPS_TARGET_CUSTOM/g edit s/VIPS_STREAMO/VIPS_TARGET/g edit s/VIPS_STREAMIU/VIPS_SOURCE_CUSTOM/g edit s/VIPS_STREAMI/VIPS_SOURCE/g edit s/VIPS_STREAM/VIPS_CONNECTION/g edit s/vips_streamou/vips_target_custom/g edit s/vips_streamo/vips_target/g edit s/vips_streamiu/vips_source_custom/g edit s/vips_streami/vips_source/g edit s/vips_stream/vips_connection/g edit s/VipsStreamou/VipsTargetCustom/g edit s/VipsStreamo/VipsTarget/g edit s/VipsStreamiu/VipsSourceCustom/g edit s/VipsStreami/VipsSource/g edit s/VipsStream/VipsConnection/g # eg. VIPS_TYPE_STREAM or VIPS_IS_STREAM edit "s/VIPS_([A-Z]+)_STREAMOU/VIPS_\1_TARGET_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMO/VIPS_\1_TARGET/g" edit "s/VIPS_([A-Z]+)_STREAMIU/VIPS_\1_SOURCE_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMI/VIPS_\1_SOURCE/g" edit "s/VIPS_([A-Z]+)_STREAM/VIPS_\1_CONNECTION/g" edit s/streamou/target_custom/g edit s/streamo/target/g edit s/streamiu/source_custom/g edit s/streami/source/g # various identifiers which also change edit s/is_a_stream/is_a_source/g edit s/find_load_stream/find_load_source/g edit s/find_save_stream/find_save_target/g edit s/new_from_stream/new_from_source/g edit s/write_to_stream/write_to_target/g edit s/vips_thumbnail_stream/vips_thumbnail_source/g # eg. vips_webpload_stream edit "s/vips_([a-z]+)load_stream/vips_\1load_source/g" # eg. vips_webpsave_stream edit "s/vips_([a-z]+)save_stream/vips_\1save_target/g" mv rename $i done ```
2019-12-29 22:40:21 +01:00
VipsSource *source;
VipsImage *image, *x;
GSList *list;
double average;
if( VIPS_INIT( argv[0] ) )
vips_error_exit( "unable to start" );
2019-10-06 11:55:19 +02:00
if( argc != 2 )
vips_error_exit( "usage: %s test-image", argv[0] );
list = get_open_files();
if( list == NULL )
/* Probably not linux, silent success.
*/
return( 0 );
/* This is usually a list of 4 files. 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( "** rand open ..\n" );
experiment with renaming stream rename as VipsConnection, VipsSource, VipsTarget etc. see https://github.com/libvips/libvips/issues/1494#issuecomment-569498619 renamed with this script: ``` set -e edit() { sed -i -E "$1" rename } for i in $*; do cp $i rename edit s/VIPS_STREAMOU/VIPS_TARGET_CUSTOM/g edit s/VIPS_STREAMO/VIPS_TARGET/g edit s/VIPS_STREAMIU/VIPS_SOURCE_CUSTOM/g edit s/VIPS_STREAMI/VIPS_SOURCE/g edit s/VIPS_STREAM/VIPS_CONNECTION/g edit s/vips_streamou/vips_target_custom/g edit s/vips_streamo/vips_target/g edit s/vips_streamiu/vips_source_custom/g edit s/vips_streami/vips_source/g edit s/vips_stream/vips_connection/g edit s/VipsStreamou/VipsTargetCustom/g edit s/VipsStreamo/VipsTarget/g edit s/VipsStreamiu/VipsSourceCustom/g edit s/VipsStreami/VipsSource/g edit s/VipsStream/VipsConnection/g # eg. VIPS_TYPE_STREAM or VIPS_IS_STREAM edit "s/VIPS_([A-Z]+)_STREAMOU/VIPS_\1_TARGET_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMO/VIPS_\1_TARGET/g" edit "s/VIPS_([A-Z]+)_STREAMIU/VIPS_\1_SOURCE_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMI/VIPS_\1_SOURCE/g" edit "s/VIPS_([A-Z]+)_STREAM/VIPS_\1_CONNECTION/g" edit s/streamou/target_custom/g edit s/streamo/target/g edit s/streamiu/source_custom/g edit s/streami/source/g # various identifiers which also change edit s/is_a_stream/is_a_source/g edit s/find_load_stream/find_load_source/g edit s/find_save_stream/find_save_target/g edit s/new_from_stream/new_from_source/g edit s/write_to_stream/write_to_target/g edit s/vips_thumbnail_stream/vips_thumbnail_source/g # eg. vips_webpload_stream edit "s/vips_([a-z]+)load_stream/vips_\1load_source/g" # eg. vips_webpsave_stream edit "s/vips_([a-z]+)save_stream/vips_\1save_target/g" mv rename $i done ```
2019-12-29 22:40:21 +01:00
if( !(source = vips_source_new_from_file( argv[1] )) )
goto error;
experiment with renaming stream rename as VipsConnection, VipsSource, VipsTarget etc. see https://github.com/libvips/libvips/issues/1494#issuecomment-569498619 renamed with this script: ``` set -e edit() { sed -i -E "$1" rename } for i in $*; do cp $i rename edit s/VIPS_STREAMOU/VIPS_TARGET_CUSTOM/g edit s/VIPS_STREAMO/VIPS_TARGET/g edit s/VIPS_STREAMIU/VIPS_SOURCE_CUSTOM/g edit s/VIPS_STREAMI/VIPS_SOURCE/g edit s/VIPS_STREAM/VIPS_CONNECTION/g edit s/vips_streamou/vips_target_custom/g edit s/vips_streamo/vips_target/g edit s/vips_streamiu/vips_source_custom/g edit s/vips_streami/vips_source/g edit s/vips_stream/vips_connection/g edit s/VipsStreamou/VipsTargetCustom/g edit s/VipsStreamo/VipsTarget/g edit s/VipsStreamiu/VipsSourceCustom/g edit s/VipsStreami/VipsSource/g edit s/VipsStream/VipsConnection/g # eg. VIPS_TYPE_STREAM or VIPS_IS_STREAM edit "s/VIPS_([A-Z]+)_STREAMOU/VIPS_\1_TARGET_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMO/VIPS_\1_TARGET/g" edit "s/VIPS_([A-Z]+)_STREAMIU/VIPS_\1_SOURCE_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMI/VIPS_\1_SOURCE/g" edit "s/VIPS_([A-Z]+)_STREAM/VIPS_\1_CONNECTION/g" edit s/streamou/target_custom/g edit s/streamo/target/g edit s/streamiu/source_custom/g edit s/streami/source/g # various identifiers which also change edit s/is_a_stream/is_a_source/g edit s/find_load_stream/find_load_source/g edit s/find_save_stream/find_save_target/g edit s/new_from_stream/new_from_source/g edit s/write_to_stream/write_to_target/g edit s/vips_thumbnail_stream/vips_thumbnail_source/g # eg. vips_webpload_stream edit "s/vips_([a-z]+)load_stream/vips_\1load_source/g" # eg. vips_webpsave_stream edit "s/vips_([a-z]+)save_stream/vips_\1save_target/g" mv rename $i done ```
2019-12-29 22:40:21 +01:00
if( !(image = vips_image_new_from_source( source, "",
"access", VIPS_ACCESS_RANDOM,
NULL )) )
goto error;
if( !fd_check( "header read", list ) )
goto error;
/* 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 ) )
goto error;
g_object_unref( x );
if( !fd_check( "first read", list ) )
goto error;
/* 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 ) )
goto error;
g_object_unref( x );
if( !fd_check( "second read", list ) )
goto error;
/* Clean up, and we should still just have three open.
*/
printf( "** unref ..\n" );
g_object_unref( image );
experiment with renaming stream rename as VipsConnection, VipsSource, VipsTarget etc. see https://github.com/libvips/libvips/issues/1494#issuecomment-569498619 renamed with this script: ``` set -e edit() { sed -i -E "$1" rename } for i in $*; do cp $i rename edit s/VIPS_STREAMOU/VIPS_TARGET_CUSTOM/g edit s/VIPS_STREAMO/VIPS_TARGET/g edit s/VIPS_STREAMIU/VIPS_SOURCE_CUSTOM/g edit s/VIPS_STREAMI/VIPS_SOURCE/g edit s/VIPS_STREAM/VIPS_CONNECTION/g edit s/vips_streamou/vips_target_custom/g edit s/vips_streamo/vips_target/g edit s/vips_streamiu/vips_source_custom/g edit s/vips_streami/vips_source/g edit s/vips_stream/vips_connection/g edit s/VipsStreamou/VipsTargetCustom/g edit s/VipsStreamo/VipsTarget/g edit s/VipsStreamiu/VipsSourceCustom/g edit s/VipsStreami/VipsSource/g edit s/VipsStream/VipsConnection/g # eg. VIPS_TYPE_STREAM or VIPS_IS_STREAM edit "s/VIPS_([A-Z]+)_STREAMOU/VIPS_\1_TARGET_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMO/VIPS_\1_TARGET/g" edit "s/VIPS_([A-Z]+)_STREAMIU/VIPS_\1_SOURCE_CUSTOM/g" edit "s/VIPS_([A-Z]+)_STREAMI/VIPS_\1_SOURCE/g" edit "s/VIPS_([A-Z]+)_STREAM/VIPS_\1_CONNECTION/g" edit s/streamou/target_custom/g edit s/streamo/target/g edit s/streamiu/source_custom/g edit s/streami/source/g # various identifiers which also change edit s/is_a_stream/is_a_source/g edit s/find_load_stream/find_load_source/g edit s/find_save_stream/find_save_target/g edit s/new_from_stream/new_from_source/g edit s/write_to_stream/write_to_target/g edit s/vips_thumbnail_stream/vips_thumbnail_source/g # eg. vips_webpload_stream edit "s/vips_([a-z]+)load_stream/vips_\1load_source/g" # eg. vips_webpsave_stream edit "s/vips_([a-z]+)save_stream/vips_\1save_target/g" mv rename $i done ```
2019-12-29 22:40:21 +01:00
g_object_unref( source );
printf( "** shutdown ..\n" );
vips_shutdown();
if( !fd_check( "shutdown", list ) )
goto error;
g_slist_free_full( list, g_free );
return( 0 );
error:
g_slist_free_full( list, g_free );
return( 1 );
}