diff options
Diffstat (limited to '')
-rw-r--r-- | common/ChangeLog | 10 | ||||
-rw-r--r-- | common/Makefile.am | 13 | ||||
-rw-r--r-- | common/estream.c | 95 | ||||
-rw-r--r-- | common/exechelp.c | 6 |
4 files changed, 118 insertions, 6 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index f5cae13e8..68cdb99e4 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,13 @@ +2006-10-17 Werner Koch <[email protected]> + + * estream.c (struct estream_internal, es_initialize) + (es_deinitialize, print_fun_writer, es_print): New and modified + functions to avoid tempfiles for printf style printing. + + * Makefile.am (libcommonpth_a_SOURCES): New. We now build a secon + version of the library with explicit Pth support. + * exechelp.c, estream.c: Make use of WITHOUT_GNU_PTH. + 2006-10-08 Werner Koch <[email protected]> * gpgrlhelp.c: Trun all functions into dummies if readline is not diff --git a/common/Makefile.am b/common/Makefile.am index 64c7f10d1..e5498ef68 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -20,16 +20,15 @@ ## Process this file with automake to produce Makefile.in -noinst_LIBRARIES = libcommon.a libsimple-pwquery.a libgpgrl.a +noinst_LIBRARIES = libcommon.a libcommonpth.a libsimple-pwquery.a libgpgrl.a noinst_PROGRAMS = $(module_tests) TESTS = $(module_tests) AM_CPPFLAGS = -I$(top_srcdir)/gl -AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(KSBA_CFLAGS) \ - $(PTH_CFLAGS) +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(KSBA_CFLAGS) -libcommon_a_SOURCES = \ +common_sources = \ common-defs.h \ util.h i18n.h \ errors.h \ @@ -61,6 +60,12 @@ libcommon_a_SOURCES = \ pka.c pka.h \ http.c http.h +libcommon_a_SOURCES = $(common_sources) +libcommon_a_CFLAGS = $(AM_CFLAGS) -DWITHOUT_GNU_PTH=1 + +libcommonpth_a_SOURCES = $(common_sources) +libcommonpth_a_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) + libsimple_pwquery_a_SOURCES = \ simple-pwquery.c simple-pwquery.h asshelp.c asshelp.h diff --git a/common/estream.c b/common/estream.c index 77ba0876d..e056cb7b4 100644 --- a/common/estream.c +++ b/common/estream.c @@ -30,6 +30,7 @@ #include <sys/types.h> #include <sys/file.h> #include <sys/stat.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -39,6 +40,11 @@ #include <stddef.h> #include <assert.h> +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + #ifdef HAVE_PTH # include <pth.h> #endif @@ -149,8 +155,13 @@ struct estream_internal unsigned int eof: 1; } indicators; unsigned int deallocate_buffer: 1; + unsigned int print_err: 1; /* Error in print_fun_writer. */ + int print_errno; /* Errno from print_fun_writer. */ + size_t print_ntotal; /* Bytes written from in print_fun_writer. */ + FILE *print_fp; /* Stdio stream used by print_fun_writer. */ }; + typedef struct estream_internal *estream_internal_t; #define ESTREAM_LOCK(stream) ESTREAM_MUTEX_LOCK (stream->intern->lock) @@ -916,6 +927,10 @@ es_initialize (estream_t stream, stream->intern->func_close = functions.func_close; stream->intern->strategy = _IOFBF; stream->intern->fd = fd; + stream->intern->print_err = 0; + stream->intern->print_errno = 0; + stream->intern->print_ntotal = 0; + stream->intern->print_fp = NULL; stream->intern->indicators.err = 0; stream->intern->indicators.eof = 0; stream->intern->deallocate_buffer = 0; @@ -934,6 +949,14 @@ es_deinitialize (estream_t stream) es_cookie_close_function_t func_close; int err, tmp_err; + if (stream->intern->print_fp) + { + int save_errno = errno; + fclose (stream->intern->print_fp); + stream->intern->print_fp = NULL; + errno = save_errno; + } + func_close = stream->intern->func_close; err = 0; @@ -941,6 +964,7 @@ es_deinitialize (estream_t stream) SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream)); if (func_close) SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); + return err; } @@ -1625,13 +1649,80 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length, } +/* Helper for esprint. */ +#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN) +static int +print_fun_writer (void *cookie_arg, const char *buffer, size_t size) +{ + estream_t stream = cookie_arg; + size_t nwritten; + + /* We don't return an error but let es_print check whether an error + has occured. Internally we skip everything after an error. */ + if (!stream->intern->print_err) + { + if (es_writen (stream, buffer, size, &nwritten)) + { + stream->intern->print_err = 1; + stream->intern->print_errno = errno; + } + else + stream->intern->print_ntotal += nwritten; + } + return 0; +} +#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */ + + +/* The core of our printf function. This is called in locked state. */ static int es_print (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format, va_list ap) { +#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN) + + if (!stream->intern->print_fp) + { +#ifdef HAVE_FOPENCOOKIE + { + cookie_io_functions_t io = { NULL }; + io.write = print_fun_writer; + + stream->intern->print_fp = fopencookie (stream, "w", io); + } +#else /*!HAVE_FOPENCOOKIE*/ + stream->intern->print_fp = funopen (stream, NULL, + print_fun_writer, NULL, NULL); +#endif /*!HAVE_FOPENCOOKIE*/ + if (!stream->intern->print_fp) + return -1; + } + + stream->intern->print_err = 0; + stream->intern->print_errno = 0; + stream->intern->print_ntotal = 0; + + if ( vfprintf (stream->intern->print_fp, format, ap) < 0 + || fflush (stream->intern->print_fp) ) + { + stream->intern->print_errno = errno; + stream->intern->print_err = 1; + fclose (stream->intern->print_fp); + stream->intern->print_fp = NULL; + } + if (stream->intern->print_err) + { + errno = stream->intern->print_errno; + return -1; + } + + return (int)stream->intern->print_ntotal; + +#else /* No funopen or fopencookie. */ + char data[BUFFER_BLOCK_SIZE]; - size_t bytes_written; size_t bytes_read; + size_t bytes_written; FILE *tmp_stream; int err; @@ -1675,11 +1766,11 @@ es_print (estream_t ES__RESTRICT stream, goto out; out: - if (tmp_stream) fclose (tmp_stream); return err ? -1 : bytes_written; +#endif /* no funopen or fopencookie */ } diff --git a/common/exechelp.c b/common/exechelp.c index 19fb04ffa..b4700c5cd 100644 --- a/common/exechelp.c +++ b/common/exechelp.c @@ -29,6 +29,12 @@ #include <signal.h> #include <unistd.h> #include <fcntl.h> + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + #ifdef USE_GNU_PTH #include <pth.h> #endif |