diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 16 | ||||
-rw-r--r-- | common/asshelp.c | 2 | ||||
-rw-r--r-- | common/estream.c | 138 | ||||
-rw-r--r-- | common/estream.h | 8 | ||||
-rw-r--r-- | common/logging.c | 37 | ||||
-rw-r--r-- | common/logging.h | 1 | ||||
-rw-r--r-- | common/miscellaneous.c | 19 | ||||
-rw-r--r-- | common/status.h | 3 | ||||
-rw-r--r-- | common/ttyio.c | 50 | ||||
-rw-r--r-- | common/ttyio.h | 4 | ||||
-rw-r--r-- | common/util.h | 5 |
11 files changed, 181 insertions, 102 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index 6f33deee8..d9ff6a729 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,10 +1,26 @@ +2010-03-12 Werner Koch <[email protected]> + + * status.h (STATUS_ENTER): New. + + * ttyio.c (tty_fprintf): Change to use estream. + + * miscellaneous.c (print_utf8_string): Rename to print_utf8_buffer + and change FP arg to an estream. Change all callers. + (print_utf8_string2): Ditto; new name is to print_utf8_buffer2. + 2010-03-11 Werner Koch <[email protected]> + * miscellaneous.c (print_string): Remove. + * estream.c (es_setvbuf): Fix parameter check. (es_set_buffering): Allow a SIZE of 0. * asshelp.c (setup_libassuan_logging, my_libassuan_log_handler): New. * logging.c (do_logv): Add arg IGNORE_ARG_PTR. Change all callers. (log_string): New. + (log_flush): New. + (set_file_fd): Simplify by using estreams es_stderr. + + * estream.h (es_stdout, es_stderr, es_stdin): New. 2010-03-10 Werner Koch <[email protected]> diff --git a/common/asshelp.c b/common/asshelp.c index 76518485f..f9878f3b3 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -42,6 +42,8 @@ my_libassuan_log_handler (assuan_context_t ctx, void *hook, { unsigned int dbgval; + (void)ctx; + if (cat != ASSUAN_LOG_CONTROL) return 0; /* We only want the control channel messages. */ dbgval = hook? *(unsigned int*)hook : 0; diff --git a/common/estream.c b/common/estream.c index 32567e631..075a56564 100644 --- a/common/estream.c +++ b/common/estream.c @@ -213,6 +213,8 @@ struct estream_internal unsigned int eof: 1; } indicators; unsigned int deallocate_buffer: 1; + unsigned int is_stdstream:1; /* This is a standard stream. */ + unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ 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. */ @@ -302,9 +304,11 @@ mem_free (void *p) * List manipulation. */ -/* Add STREAM to the list of registered stream objects. */ +/* Add STREAM to the list of registered stream objects. If + WITH_LOCKED_LIST is true we assumed that the list of streams is + already locked. */ static int -es_list_add (estream_t stream) +es_list_add (estream_t stream, int with_locked_list) { estream_list_t list_obj; int ret; @@ -314,14 +318,16 @@ es_list_add (estream_t stream) ret = -1; else { - ESTREAM_LIST_LOCK; + if (!with_locked_list) + ESTREAM_LIST_LOCK; list_obj->car = stream; list_obj->cdr = estream_list; list_obj->prev_cdr = &estream_list; if (estream_list) estream_list->prev_cdr = &list_obj->cdr; estream_list = list_obj; - ESTREAM_LIST_UNLOCK; + if (!with_locked_list) + ESTREAM_LIST_UNLOCK; ret = 0; } @@ -330,11 +336,12 @@ es_list_add (estream_t stream) /* Remove STREAM from the list of registered stream objects. */ static void -es_list_remove (estream_t stream) +es_list_remove (estream_t stream, int with_locked_list) { estream_list_t list_obj; - ESTREAM_LIST_LOCK; + if (!with_locked_list) + ESTREAM_LIST_LOCK; for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) if (list_obj->car == stream) { @@ -344,7 +351,8 @@ es_list_remove (estream_t stream) mem_free (list_obj); break; } - ESTREAM_LIST_UNLOCK; + if (!with_locked_list) + ESTREAM_LIST_UNLOCK; } /* Type of an stream-iterator-function. */ @@ -1211,6 +1219,8 @@ es_initialize (estream_t stream, stream->intern->print_fp = NULL; stream->intern->indicators.err = 0; stream->intern->indicators.eof = 0; + stream->intern->is_stdstream = 0; + stream->intern->stdstream_fd = 0; stream->intern->deallocate_buffer = 0; stream->data_len = 0; @@ -1219,7 +1229,7 @@ es_initialize (estream_t stream, stream->unread_data_len = 0; /* Depending on the modeflags we set whether we start in writing or reading mode. This is required in case we are working on a - wronly stream which is not seeekable (like stdout). Without this + stream which is not seeekable (like stdout). Without this pre-initialization we would do a seek at the first write call and as this will fail no utput will be delivered. */ if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) ) @@ -1258,7 +1268,8 @@ es_deinitialize (estream_t stream) /* Create a new stream object, initialize it. */ static int es_create (estream_t *stream, void *cookie, int fd, - es_cookie_io_functions_t functions, unsigned int modeflags) + es_cookie_io_functions_t functions, unsigned int modeflags, + int with_locked_list) { estream_internal_t stream_internal_new; estream_t stream_new; @@ -1290,7 +1301,7 @@ es_create (estream_t *stream, void *cookie, int fd, ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock); es_initialize (stream_new, cookie, fd, functions, modeflags); - err = es_list_add (stream_new); + err = es_list_add (stream_new, with_locked_list); if (err) goto out; @@ -1312,13 +1323,13 @@ es_create (estream_t *stream, void *cookie, int fd, /* Deinitialize a stream object and destroy it. */ static int -es_destroy (estream_t stream) +es_destroy (estream_t stream, int with_locked_list) { int err = 0; if (stream) { - es_list_remove (stream); + es_list_remove (stream, with_locked_list); err = es_deinitialize (stream); mem_free (stream->intern); mem_free (stream); @@ -1838,7 +1849,7 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length, goto out; err = es_create (&line_stream, line_stream_cookie, -1, - estream_functions_mem, O_RDWR); + estream_functions_mem, O_RDWR, 0); if (err) goto out; @@ -1923,7 +1934,7 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length, out: if (line_stream) - es_destroy (line_stream); + es_destroy (line_stream, 0); else if (line_stream_cookie) es_func_mem_destroy (line_stream_cookie); @@ -2122,7 +2133,7 @@ es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_file, modeflags); + err = es_create (&stream, cookie, fd, estream_functions_file, modeflags, 0); if (err) goto out; @@ -2162,7 +2173,7 @@ es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, goto out; create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags); + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0); out: @@ -2193,7 +2204,7 @@ es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) memlimit)) return NULL; - if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags)) + if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0)) (*estream_functions_mem.func_close) (cookie); return stream; @@ -2217,7 +2228,7 @@ es_fopencookie (void *ES__RESTRICT cookie, if (err) goto out; - err = es_create (&stream, cookie, -1, functions, modeflags); + err = es_create (&stream, cookie, -1, functions, modeflags, 0); if (err) goto out; @@ -2249,7 +2260,8 @@ do_fdopen (int filedes, const char *mode, int no_close) goto out; create_called = 1; - err = es_create (&stream, cookie, filedes, estream_functions_fd, modeflags); + err = es_create (&stream, cookie, filedes, estream_functions_fd, + modeflags, 0); out: @@ -2274,7 +2286,7 @@ es_fdopen_nc (int filedes, const char *mode) estream_t -do_fpopen (FILE *fp, const char *mode, int no_close) +do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list) { unsigned int modeflags; int create_called; @@ -2298,7 +2310,7 @@ do_fpopen (FILE *fp, const char *mode, int no_close) create_called = 1; err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp, - modeflags); + modeflags, with_locked_list); out: @@ -2320,7 +2332,7 @@ do_fpopen (FILE *fp, const char *mode, int no_close) estream_t es_fpopen (FILE *fp, const char *mode) { - return do_fpopen (fp, mode, 0); + return do_fpopen (fp, mode, 0, 0); } @@ -2328,7 +2340,52 @@ es_fpopen (FILE *fp, const char *mode) estream_t es_fpopen_nc (FILE *fp, const char *mode) { - return do_fpopen (fp, mode, 1); + return do_fpopen (fp, mode, 1, 0); +} + + +estream_t +_es_get_std_stream (int fd) +{ + estream_list_t list_obj; + estream_t stream = NULL; + + fd %= 3; /* We only allow 0, 1 or 2 but we don't want to return an error. */ + ESTREAM_LIST_LOCK; + for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) + if (list_obj->car->intern->is_stdstream + && list_obj->car->intern->stdstream_fd == fd) + { + stream = list_obj->car; + break; + } + if (!stream) + { + /* Standard stream not yet created - do it now. */ + if (!fd) + stream = do_fpopen (stdin, "r", 1, 1); + else if (fd == 1) + stream = do_fpopen (stdout, "a", 1, 1); + else + stream = do_fpopen (stderr, "a", 1, 1); + + if (!stream) /* Fallback: Create a bit bucket. */ + { + stream = do_fpopen (NULL, fd? "a":"r", 0, 1); + if (!stream) + { + fprintf (stderr, "fatal: error creating a dummy estream" + " for %d: %s\n", fd, strerror (errno)); + abort(); + } + } + stream->intern->is_stdstream = 1; + stream->intern->stdstream_fd = fd; + if (fd == 2) + es_set_buffering (stream, NULL, _IOLBF, 0); + } + ESTREAM_LIST_UNLOCK; + return stream; } @@ -2370,7 +2427,7 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, if (create_called) es_func_fd_destroy (cookie); - es_destroy (stream); + es_destroy (stream, 0); stream = NULL; } else @@ -2381,7 +2438,7 @@ es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, /* FIXME? We don't support re-opening at the moment. */ _set_errno (EINVAL); es_deinitialize (stream); - es_destroy (stream); + es_destroy (stream, 0); stream = NULL; } @@ -2394,7 +2451,7 @@ es_fclose (estream_t stream) { int err; - err = es_destroy (stream); + err = es_destroy (stream, 0); return err; } @@ -2496,6 +2553,23 @@ es_clearerr (estream_t stream) } +static int +do_fflush (estream_t stream) +{ + int err; + + if (stream->flags.writing) + err = es_flush (stream); + else + { + es_empty (stream); + err = 0; + } + + return err; +} + + int es_fflush (estream_t stream) { @@ -2504,17 +2578,11 @@ es_fflush (estream_t stream) if (stream) { ESTREAM_LOCK (stream); - if (stream->flags.writing) - err = es_flush (stream); - else - { - es_empty (stream); - err = 0; - } + err = do_fflush (stream); ESTREAM_UNLOCK (stream); } else - err = es_list_iterate (es_fflush); + err = es_list_iterate (do_fflush); return err ? EOF : 0; } @@ -3186,7 +3254,7 @@ es_tmpfile (void) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags); + err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0); out: diff --git a/common/estream.h b/common/estream.h index 477aface8..67856bf76 100644 --- a/common/estream.h +++ b/common/estream.h @@ -80,6 +80,7 @@ #define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) #define es_fpopen _ESTREAM_PREFIX(es_fpopen) #define es_fpopen_nc _ESTREAM_PREFIX(es_fpopen_nc) +#define _es_get_std_stream _ESTREAM_PREFIX(_es_get_std_stream) #define es_freopen _ESTREAM_PREFIX(es_freopen) #define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) #define es_fclose _ESTREAM_PREFIX(es_fclose) @@ -250,6 +251,13 @@ int es_fclose (estream_t stream); int es_fileno (estream_t stream); int es_fileno_unlocked (estream_t stream); +estream_t _es_get_std_stream (int fd); + +#define es_stdin _es_get_std_stream (0) +#define es_stdout _es_get_std_stream (1) +#define es_stderr _es_get_std_stream (2) + + void es_flockfile (estream_t stream); int es_ftrylockfile (estream_t stream); void es_funlockfile (estream_t stream); diff --git a/common/logging.c b/common/logging.c index 3b767cb97..6bc35eee5 100644 --- a/common/logging.c +++ b/common/logging.c @@ -283,32 +283,7 @@ set_file_fd (const char *name, int fd) /* On error default to a stderr based estream. */ if (!fp) - { - fp = es_fpopen (stderr, "a"); - if (fp) - { - if (name) - es_fprintf (fp, "failed to open log file `%s': %s\n", - name, strerror (errno)); - else - es_fprintf (fp, "failed to fdopen file descriptor %d: %s\n", - fd, strerror (errno)); - } - else - { - fprintf (stderr, "failed to use stderr as log stream: %s\n", - strerror (errno)); - /* No way to log something. Create a dummy estream so that - there is something we can use. */ - fp = es_fpopen (NULL, "a"); - if (!fp) - { - fprintf (stderr, "fatal: failed to open dummy stream: %s\n", - strerror (errno)); - abort(); - } - } - } + fp = es_stderr; es_setvbuf (fp, NULL, _IOLBF, 0); @@ -605,6 +580,16 @@ log_printf (const char *fmt, ...) } +/* Flush the log - this is useful to make sure that the trailing + linefeed has been printed. */ +void +log_flush (void) +{ + volatile va_list dummy_arg_ptr; + do_logv (JNLIB_LOG_CONT, 1, NULL, dummy_arg_ptr); +} + + /* Print a hexdump of BUFFER. With TEXT of NULL print just the raw dump, with TEXT just an empty string, print a trailing linefeed, otherwise print an entire debug line. */ diff --git a/common/logging.h b/common/logging.h index f089cf0b5..2c29a0b1b 100644 --- a/common/logging.h +++ b/common/logging.h @@ -75,6 +75,7 @@ void log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); void log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); void log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); void log_printf( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2); +void log_flush (void); /* Print a hexdump of BUFFER. With TEXT passes as NULL print just the raw dump, with TEXT being an empty string, print a trailing diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 396f7224f..01d8c97be 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -117,23 +117,22 @@ print_fname_stdin (const char *s) return s; } -/* fixme: Globally replace it by print_sanitized_buffer. */ -void -print_string( FILE *fp, const byte *p, size_t n, int delim ) -{ - print_sanitized_buffer (fp, p, n, delim); -} void -print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim ) +print_utf8_buffer2 (estream_t stream, const void *p, size_t n, int delim) { - print_sanitized_utf8_buffer (fp, p, n, delim); + char tmp[2]; + + tmp[0] = delim; + tmp[1] = 0; + es_write_sanitized_utf8_buffer (stream, p, n, tmp, NULL); } + void -print_utf8_string( FILE *fp, const byte *p, size_t n ) +print_utf8_buffer (estream_t stream, const void *p, size_t n) { - print_utf8_string2 (fp, p, n, 0); + es_write_sanitized_utf8_buffer (stream, p, n, NULL, NULL); } /* Write LENGTH bytes of BUFFER to FP as a hex encoded string. diff --git a/common/status.h b/common/status.h index bb5429dc0..0533c4a92 100644 --- a/common/status.h +++ b/common/status.h @@ -126,7 +126,8 @@ enum STATUS_TRUNCATED, STATUS_MOUNTPOINT, - STATUS_ERROR + STATUS_ERROR, + STATUS_SUCCESS }; diff --git a/common/ttyio.c b/common/ttyio.c index ec26b06e8..4f30b4b44 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -1,6 +1,6 @@ /* ttyio.c - tty i/O functions * Copyright (C) 1998,1999,2000,2001,2002,2003,2004,2006,2007, - * 2009 Free Software Foundation, Inc. + * 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -244,14 +244,14 @@ tty_printf( const char *fmt, ... ) /* Same as tty_printf but if FP is not NULL, behave like a regular fprintf. */ void -tty_fprintf (FILE *fp, const char *fmt, ... ) +tty_fprintf (estream_t fp, const char *fmt, ... ) { va_list arg_ptr; if (fp) { va_start (arg_ptr, fmt) ; - vfprintf (fp, fmt, arg_ptr ); + es_vfprintf (fp, fmt, arg_ptr ); va_end (arg_ptr); return; } @@ -259,32 +259,32 @@ tty_fprintf (FILE *fp, const char *fmt, ... ) if (no_terminal) return; - if( !initialized ) - init_ttyfp(); + if (!initialized) + init_ttyfp (); - va_start( arg_ptr, fmt ) ; + va_start (arg_ptr, fmt); #ifdef _WIN32 - { - char *buf = NULL; - int n; - DWORD nwritten; - - n = vasprintf(&buf, fmt, arg_ptr); - if( !buf ) - log_bug("vasprintf() failed\n"); - - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); - last_prompt_len += n; - xfree (buf); - } + { + char *buf = NULL; + int n; + DWORD nwritten; + + n = vasprintf(&buf, fmt, arg_ptr); + if (!buf) + log_bug("vasprintf() failed\n"); + + if (!WriteConsoleA( con.out, buf, n, &nwritten, NULL )) + log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); + if (n != nwritten) + log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); + last_prompt_len += n; + xfree (buf); + } #else - last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; - fflush(ttyfp); + last_prompt_len += vfprintf(ttyfp,fmt,arg_ptr) ; + fflush(ttyfp); #endif - va_end(arg_ptr); + va_end(arg_ptr); } diff --git a/common/ttyio.h b/common/ttyio.h index eb2116a02..e1dc0f053 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -28,13 +28,13 @@ int tty_batchmode (int onoff); #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) void tty_printf (const char *fmt, ... ) __attribute__ ((format (printf,1,2))); -void tty_fprintf (FILE *fp, const char *fmt, ... ) +void tty_fprintf (estream_t fp, const char *fmt, ... ) __attribute__ ((format (printf,2,3))); char *tty_getf (const char *promptfmt, ... ) __attribute__ ((format (printf,1,2))); #else void tty_printf (const char *fmt, ... ); -void tty_fprintf (FILE *fp, const char *fmt, ... ); +void tty_fprintf (estream_t fp, const char *fmt, ... ); char *tty_getf (const char *promptfmt, ... ); #endif void tty_print_string (const unsigned char *p, size_t n); diff --git a/common/util.h b/common/util.h index 32d4085e7..6deee38e1 100644 --- a/common/util.h +++ b/common/util.h @@ -278,9 +278,8 @@ char *xtryasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2); const char *print_fname_stdout (const char *s); const char *print_fname_stdin (const char *s); -void print_string (FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim); -void print_utf8_string (FILE *fp, const byte *p, size_t n); +void print_utf8_buffer2 (estream_t fp, const void *p, size_t n, int delim); +void print_utf8_buffer (estream_t fp, const void *p, size_t n); void print_hexstring (FILE *fp, const void *buffer, size_t length, int reserved); char *make_printable_string (const void *p, size_t n, int delim); |