From 4fce90fabb710c38358f39d3e16bdb63f2f0c60f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 10 Sep 2009 10:44:10 +0000 Subject: [PATCH] stuff --- ChangeLog | 2 + libvips/conversion/im_system.c | 173 +++++++---------------- libvips/deprecated/deprecated_dispatch.c | 1 + libvips/deprecated/im_cmulnorm.c | 1 + libvips/deprecated/im_fav4.c | 1 + libvips/deprecated/im_gadd.c | 1 + libvips/deprecated/im_litecor.c | 1 + libvips/iofuncs/im_close.c | 36 ++--- 8 files changed, 81 insertions(+), 135 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60261618..1c24a4f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,8 @@ - faster, simpler, better im_max(), im_min, im_avg(), im_deviate() - im_max() returns true modulus, not square of modulus, for complex images - im_avg() works for complex, returning average modulus +- im_system() fix (thanks Roland) +- im_system() rewrite - im_maxpos()/im_minpos() are partial and work for complex - im_max()/im_min() are now convenience functions - im_maxpos_avg() handles complex and multi-band images diff --git a/libvips/conversion/im_system.c b/libvips/conversion/im_system.c index 419379bb..8ee0f852 100644 --- a/libvips/conversion/im_system.c +++ b/libvips/conversion/im_system.c @@ -8,6 +8,10 @@ * - out can be NULL * 23/12/04 * - use g_mkstemp() + * 8/9/09 + * - add .v suffix (thanks Roland) + * - use vipsbuf + * - rewrite to make it simpler */ /* @@ -62,88 +66,8 @@ #ifdef OS_WIN32 #define popen(b,m) _popen(b,m) #define pclose(f) _pclose(f) -#define mktemp(f) _mktemp(f) #endif /*OS_WIN32*/ -/* A string being written to ... multiple calls to buf_append add to it, on - * overflow append "..." and block further writes. - */ -typedef struct { - char *base; /* String base */ - int mx; /* Maximum length */ - int i; /* Current write point */ - int full; /* String has filled, block writes */ - int lasti; /* For read-recent */ -} BufInfo; - -/* Set to start state. - */ -static void -buf_rewind( BufInfo *buf ) -{ - buf->i = 0; - buf->lasti = 0; - buf->full = 0; - - strcpy( buf->base, "" ); -} - -/* Init a buf struct. - */ -static void -buf_init( BufInfo *buf, char *base, int mx ) -{ - buf->base = base; - buf->mx = mx; - buf_rewind( buf ); -} - -/* Append string to buf. Error on overflow. - */ -static int -buf_appends( BufInfo *buf, const char *str ) -{ - int len; - int avail; - int cpy; - - if( buf->full ) - return( 0 ); - - /* Amount we want to copy. - */ - len = strlen( str ); - - /* Space available. - */ - avail = buf->mx - buf->i - 4; - - /* Amount we actually copy. - */ - cpy = IM_MIN( len, avail ); - - strncpy( buf->base + buf->i, str, cpy ); - buf->i += cpy; - - if( buf->i >= buf->mx - 4 ) { - buf->full = 1; - strcpy( buf->base + buf->mx - 4, "..." ); - buf->i = buf->mx - 1; - return( 0 ); - } - - return( 1 ); -} - -/* Read all text from buffer. - */ -static char * -buf_all( BufInfo *buf ) -{ - buf->base[buf->i] = '\0'; - return( buf->base ); -} - /* Do popen(), with printf-style args. */ static FILE * @@ -151,12 +75,53 @@ popenf( const char *fmt, const char *mode, ... ) { va_list args; char buf[IM_MAX_STRSIZE]; + FILE *fp; va_start( args, mode ); (void) im_vsnprintf( buf, IM_MAX_STRSIZE, fmt, args ); va_end( args ); - return( popen( buf, mode ) ); + if( !(fp = popen( buf, mode )) ) { + im_error( "popenf", "%s", strerror( errno ) ); + return( NULL ); + } + + return( fp ); +} + +/* Make a disc IMAGE which will be automatically unlinked on im_close(). + */ +static IMAGE * +system_temp( void ) +{ + const char *tmpd; + char name[IM_MAX_STRSIZE]; + int fd; + IMAGE *disc; + + if( !(tmpd = g_getenv( "TMPDIR" )) ) + tmpd = "/tmp"; + strcpy( name, tmpd ); + strcat( name, "/vips_XXXXXX.v" ); + + if( (fd = g_mkstemp( name )) == -1 ) { + im_error( "im_system", + _( "unable to make temp file %s" ), name ); + return( NULL ); + } + close( fd ); + + if( !(disc = im_open( name, "w" )) ) { + unlink( name ); + return( NULL ); + } + if( im_add_close_callback( disc, + (im_callback_fn) unlink, disc->filename, NULL ) ) { + im_close( disc ); + unlink( name ); + } + + return( disc ); } /* Run a command on an IMAGE ... copy to tmp (if necessary), run @@ -165,61 +130,33 @@ popenf( const char *fmt, const char *mode, ... ) int im_system( IMAGE *im, const char *cmd, char **out ) { - char *filename = im->filename; - int delete = 0; FILE *fp; if( !im_isfile( im ) ) { - const char *tmpd; - char name[IM_MAX_STRSIZE]; IMAGE *disc; - if( !(tmpd = g_getenv( "TMPDIR" )) ) - tmpd = "/tmp"; - strcpy( name, tmpd ); - strcat( name, "/vips_XXXXXX" ); - - close( g_mkstemp( name ) ); - filename = im_strdup( NULL, name ); - - if( !(disc = im_open( filename, "w" )) ) { - unlink( filename ); - free( filename ); + if( !(disc = system_temp()) ) return( -1 ); - } - if( im_copy( im, disc ) ) { + if( im_copy( im, disc ) || + im_system( disc, cmd, out ) ) { im_close( disc ); - unlink( filename ); - free( filename ); return( -1 ); } im_close( disc ); - delete = 1; } - - if( (fp = popenf( cmd, "r", filename )) ) { + else if( (fp = popenf( cmd, "r", im->filename )) ) { char line[IM_MAX_STRSIZE]; - BufInfo buf; - char txt_buffer[IM_MAX_STRSIZE]; + VipsBuf buf; + char str[IM_MAX_STRSIZE]; - buf_init( &buf, txt_buffer, IM_MAX_STRSIZE ); + vips_buf_init_static( &buf, str, IM_MAX_STRSIZE ); while( fgets( line, IM_MAX_STRSIZE, fp ) ) - if( !buf_appends( &buf, line ) ) + if( !vips_buf_appends( &buf, line ) ) break; pclose( fp ); if( out ) - *out = im_strdup( NULL, buf_all( &buf ) ); - } - - if( delete ) { - unlink( filename ); - im_free( filename ); - } - - if( !fp ) { - im_errormsg( "popen: %s", strerror( errno ) ); - return( -1 ); + *out = im_strdup( NULL, vips_buf_all( &buf ) ); } return( 0 ); diff --git a/libvips/deprecated/deprecated_dispatch.c b/libvips/deprecated/deprecated_dispatch.c index bfa93607..7f8078bf 100644 --- a/libvips/deprecated/deprecated_dispatch.c +++ b/libvips/deprecated/deprecated_dispatch.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef WITH_DMALLOC #include diff --git a/libvips/deprecated/im_cmulnorm.c b/libvips/deprecated/im_cmulnorm.c index 7d4014d1..973e63b4 100644 --- a/libvips/deprecated/im_cmulnorm.c +++ b/libvips/deprecated/im_cmulnorm.c @@ -46,6 +46,7 @@ #include #include +#include #include #include diff --git a/libvips/deprecated/im_fav4.c b/libvips/deprecated/im_fav4.c index 2a9878e2..1e85af50 100644 --- a/libvips/deprecated/im_fav4.c +++ b/libvips/deprecated/im_fav4.c @@ -37,6 +37,7 @@ Copyright (C) 1992, Kirk Martinez, History of Art Dept, Birkbeck College #include #include +#include #ifdef WITH_DMALLOC #include diff --git a/libvips/deprecated/im_gadd.c b/libvips/deprecated/im_gadd.c index 92952ee6..e1b26519 100644 --- a/libvips/deprecated/im_gadd.c +++ b/libvips/deprecated/im_gadd.c @@ -56,6 +56,7 @@ #include #include +#include #ifdef WITH_DMALLOC #include diff --git a/libvips/deprecated/im_litecor.c b/libvips/deprecated/im_litecor.c index 9b4aa577..0d106232 100644 --- a/libvips/deprecated/im_litecor.c +++ b/libvips/deprecated/im_litecor.c @@ -65,6 +65,7 @@ #include #include +#include #ifdef WITH_DMALLOC #include diff --git a/libvips/iofuncs/im_close.c b/libvips/iofuncs/im_close.c index 70dd3d45..47f1debb 100644 --- a/libvips/iofuncs/im_close.c +++ b/libvips/iofuncs/im_close.c @@ -44,7 +44,7 @@ * 16/1/04 JC * - frees as much as possible on im_close() failure * 6/6/05 Markus Wollgarten - * - free Meta on close + * - free Meta on close * 30/6/05 JC * - actually, free Meta on final close, so we carry meta over on an * im__close()/im_openin() pair (eg. see im_pincheck()) @@ -57,7 +57,12 @@ * 23/7/08 * - im__close() will no longer free regions * 9/8/08 - * - lock global image list (thanks lee) + * - lock global image list (thanks Lee) + * 8/9/09 + * - move close callbacks *after* we have released resources --- we + * can now write close callbacks that unlink() temporary files + * - use preclose callbacks if you want to run before resources are + * released */ /* @@ -168,15 +173,6 @@ im__close( IMAGE *im ) im_window_print( (im_window_t *) p->data ); } - /* Junk all callbacks, perform close callbacks. - */ - IM_FREEF( im_slist_free_all, im->evalstartfns ); - IM_FREEF( im_slist_free_all, im->evalfns ); - IM_FREEF( im_slist_free_all, im->evalendfns ); - IM_FREEF( im_slist_free_all, im->invalidatefns ); - result |= im__trigger_callbacks( im->closefns ); - IM_FREEF( im_slist_free_all, im->closefns ); - /* Junk generate functions. */ im->start = NULL; @@ -208,14 +204,11 @@ im__close( IMAGE *im ) printf( "im__close: closing output file ..\n" ); #endif /*DEBUG_IO*/ - if( im->dtype == IM_OPENOUT && im__writehist( im ) ) { - im_errormsg( "im_close: unable to write metadata " - "for %s", im->filename ); + if( im->dtype == IM_OPENOUT && im__writehist( im ) ) result = -1; - } if( close( im->fd ) == -1 ) { - im_errormsg( "im_close: unable to close fd (2) " - "for %s", im->filename ); + im_error( "im_close", _( "unable to close fd for %s" ), + im->filename ); result = -1; } im->fd = -1; @@ -237,6 +230,15 @@ im__close( IMAGE *im ) im->data = NULL; } + /* Junk all callbacks, perform close callbacks. + */ + IM_FREEF( im_slist_free_all, im->evalstartfns ); + IM_FREEF( im_slist_free_all, im->evalfns ); + IM_FREEF( im_slist_free_all, im->evalendfns ); + IM_FREEF( im_slist_free_all, im->invalidatefns ); + result |= im__trigger_callbacks( im->closefns ); + IM_FREEF( im_slist_free_all, im->closefns ); + /* Reset other state. */ im->dtype = IM_NONE;