From: Marcus Brinkmann Date: Wed, 8 May 2002 03:57:42 +0000 (+0000) Subject: 2002-05-08 Marcus Brinkmann X-Git-Tag: gpgme-0-3-7~30 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5d03d9b7ebbe811623b4066ea5e5fe3bf5d6f746;p=gpgme.git 2002-05-08 Marcus Brinkmann * debug.h: New file. * Makefile.am (libgpgme_la_SOURCES): Add debug.h. * util.h: Removed all prototypes and declarations related to debugging. Include "debug.h". * debug.c (debug_level): Comment variable and remove superfluous zero initializer. (errfp): Likewise. (_gpgme_debug_enabled): Function removed. (struct debug_control_s): Definition removed. (_gpgme_debug_level): Function removed. (_gpgme_debug_begin): Rewritten to use vasprintf. Accept a pritnf-style format specification and a variable number of arguments. (_gpgme_debug_add): Rewritten using vasprintf. Expect that format starts out with "%s" for simplicity. (_gpgme_debug_end): Rewritten using vasprintf. Do not accept a TEXT argument anymore. * posix-io.c (_gpgme_io_select): Use new level argument for DEBUG_BEGIN instead explicit if construct. * debug.c (debug_init): Remove superfluous zero initializer, remove volatile flag of INITIALIZED. Do not use the double-checked locking algorithm, it is fundamentally flawed and will empty your fridge (on a more serious note, despite the volatile flag it doesn't give you the guarantee you would expect, for example on a DEC Alpha or an SMP machine. The volatile only serializes accesses to the volatile variable, but not to the other variables). --- diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 9ece8fb..200dfea 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,36 @@ +2002-05-08 Marcus Brinkmann + + * debug.h: New file. + * Makefile.am (libgpgme_la_SOURCES): Add debug.h. + * util.h: Removed all prototypes and declarations related to + debugging. Include "debug.h". + + * debug.c (debug_level): Comment variable and remove superfluous + zero initializer. + (errfp): Likewise. + (_gpgme_debug_enabled): Function removed. + (struct debug_control_s): Definition removed. + (_gpgme_debug_level): Function removed. + (_gpgme_debug_begin): Rewritten to use vasprintf. Accept a + pritnf-style format specification and a variable number of + arguments. + (_gpgme_debug_add): Rewritten using vasprintf. Expect that format + starts out with "%s" for simplicity. + (_gpgme_debug_end): Rewritten using vasprintf. Do not accept a + TEXT argument anymore. + + * posix-io.c (_gpgme_io_select): Use new level argument for + DEBUG_BEGIN instead explicit if construct. + + * debug.c (debug_init): Remove superfluous zero initializer, + remove volatile flag of INITIALIZED. Do not use the + double-checked locking algorithm, it is fundamentally flawed and + will empty your fridge (on a more serious note, despite the + volatile flag it doesn't give you the guarantee you would expect, + for example on a DEC Alpha or an SMP machine. The volatile only + serializes accesses to the volatile variable, but not to the other + variables). + 2002-05-03 Werner Koch * engine-gpgsm.c (_gpgme_gpgsm_new): Redirect any gpgsm error diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 161dc97..93341a1 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -68,7 +68,8 @@ libgpgme_la_SOURCES = \ sema.h io.h \ ${system_components} \ mutex.h \ - gpgme.c debug.c version.c errors.c + debug.c debug.h \ + gpgme.c version.c errors.c errors.c : gpgme.h $(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c diff --git a/gpgme/debug.c b/gpgme/debug.c index 8770768..06ab1bc 100644 --- a/gpgme/debug.c +++ b/gpgme/debug.c @@ -1,5 +1,5 @@ -/* debug.c - * Copyright (C) 2001 g10 Code GmbH +/* debug.c - helpful output in desperate situations + * Copyright (C) 2001, 2002 g10 Code GmbH * * This file is part of GPGME. * @@ -35,206 +35,175 @@ #include "util.h" #include "sema.h" + +/* Lock to serialize initialization of the debug output subsystem and + output of actual debug messages. */ DEFINE_STATIC_LOCK (debug_lock); -struct debug_control_s { - FILE *fp; - char fname[100]; -}; +/* The amount of detail requested by the user, per environment + variable GPGME_DEBUG. */ +static int debug_level; -static int debug_level = 0; -static FILE *errfp = NULL; +/* The output stream for the debug messages. */ +static FILE *errfp; -/**************** - * remove leading and trailing white spaces - */ + +/* Remove leading and trailing white spaces. */ static char * -trim_spaces( char *str ) +trim_spaces (char *str) { - char *string, *p, *mark; - - string = str; - /* find first non space character */ - for( p=string; *p && isspace( *(byte*)p ) ; p++ ) - ; - /* move characters */ - for( (mark = NULL); (*string = *p); string++, p++ ) - if( isspace( *(byte*)p ) ) { - if( !mark ) - mark = string ; - } - else - mark = NULL ; - if( mark ) - *mark = '\0' ; /* remove trailing spaces */ - - return str ; + char *string, *p, *mark; + + string = str; + /* Find first non space character. */ + for (p = string; *p && isspace (*(byte *) p); p++) + ; + /* Move characters. */ + for (mark = NULL; (*string = *p); string++, p++) + if (isspace (*(byte *) p)) + { + if (!mark) + mark = string; + } + else + mark = NULL; + if (mark) + *mark = '\0'; /* Remove trailing spaces. */ + + return str; } static void debug_init (void) { - static volatile int initialized = 0; - - if (initialized) - return; - LOCK (debug_lock); - if (!initialized) { - const char *e = getenv ("GPGME_DEBUG"); - const char *s1, *s2;; - - initialized = 1; - debug_level = 0; - errfp = stderr; - if (e) { - debug_level = atoi (e); - s1 = strchr (e, ':'); - if (s1 + static int initialized; + + LOCK (debug_lock); + if (!initialized) + { + const char *e = getenv ("GPGME_DEBUG"); + const char *s1, *s2;; + + initialized = 1; + errfp = stderr; + if (e) + { + debug_level = atoi (e); + s1 = strchr (e, ':'); + if (s1) + { #ifndef HAVE_DOSISH_SYSTEM - && getuid () == geteuid () + if (getuid () == geteuid ()) + { #endif - ) { - char *p; - FILE *fp; - - s1++; - if ( !(s2 = strchr (s1, ':')) ) - s2 = s1 + strlen(s1); - p = xtrymalloc (s2-s1+1); - if (p) { - memcpy (p, s1, s2-s1); - p[s2-s1] = 0; - trim_spaces (p); - fp = fopen (p,"a"); - if (fp) { - setvbuf (fp, NULL, _IOLBF, 0); - errfp = fp; - } - xfree (p); - } - } + char *p; + FILE *fp; + + s1++; + if (!(s2 = strchr (s1, ':'))) + s2 = s1 + strlen (s1); + p = xtrymalloc (s2 - s1 + 1); + if (p) + { + memcpy (p, s1, s2 - s1); + p[s2-s1] = 0; + trim_spaces (p); + fp = fopen (p,"a"); + if (fp) + { + setvbuf (fp, NULL, _IOLBF, 0); + errfp = fp; + } + xfree (p); + } +#ifndef HAVE_DOSISH_SYSTEM + } +#endif + } } - if (debug_level > 0) - fprintf (errfp,"gpgme_debug: level=%d\n", debug_level); + if (debug_level > 0) + fprintf (errfp, "gpgme_debug: level=%d\n", debug_level); } - UNLOCK (debug_lock); -} - -int -_gpgme_debug_level () -{ - return debug_level; + UNLOCK (debug_lock); } + +/* Log the formatted string FORMAT at debug level LEVEL or higher. */ void _gpgme_debug (int level, const char *format, ...) { - va_list arg_ptr ; + va_list arg_ptr; - debug_init (); - if ( debug_level < level ) - return; + debug_init (); + if (debug_level < level) + return; - va_start ( arg_ptr, format ) ; - LOCK (debug_lock); - vfprintf (errfp, format, arg_ptr) ; - va_end ( arg_ptr ) ; - if( format && *format && format[strlen(format)-1] != '\n' ) - putc ('\n', errfp); - UNLOCK (debug_lock); - fflush (errfp); + va_start (arg_ptr, format); + LOCK (debug_lock); + vfprintf (errfp, format, arg_ptr); + va_end (arg_ptr); + if(format && *format && format[strlen (format) - 1] != '\n') + putc ('\n', errfp); + UNLOCK (debug_lock); + fflush (errfp); } - +/* Start a new debug line in *LINE, logged at level LEVEL or higher, + and starting with the formatted string FORMAT. */ void -_gpgme_debug_begin ( void **helper, int level, const char *text) +_gpgme_debug_begin (void **line, int level, const char *format, ...) { - struct debug_control_s *ctl; - - debug_init (); - - *helper = NULL; - if ( debug_level < level ) - return; - ctl = xtrycalloc (1, sizeof *ctl ); - if (!ctl) { - _gpgme_debug (255, __FILE__ ":" STR2(__LINE__)": out of core"); - return; - } + va_list arg_ptr; - /* Oh what a pitty that we don't have a asprintf or snprintf under - * Windoze. We definitely should write our own clib for W32! */ - sprintf ( ctl->fname, "/tmp/gpgme_debug.%d.%p", getpid (), ctl ); - #if defined (__GLIBC__) || defined (HAVE_DOSISH_SYSTEM) - ctl->fp = fopen (ctl->fname, "w+x"); - #else + debug_init (); + if (debug_level < level) { - int fd = open (ctl->fname, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, - S_IRUSR|S_IWUSR ); - if (fd == -1) - ctl->fp = NULL; - else - ctl->fp = fdopen (fd, "w+"); + /* Disable logging of this line. */ + *line = NULL; + return; } - #endif - if (!ctl->fp) { - _gpgme_debug (255,__FILE__ ":" STR2(__LINE__)": failed to create `%s'", - ctl->fname ); - xfree (ctl); - return; - } - *helper = ctl; - _gpgme_debug_add (helper, "%s", text ); -} -int -_gpgme_debug_enabled (void **helper) -{ - return helper && *helper; + va_start (arg_ptr, format); + vasprintf ((char **) line, format, arg_ptr); + va_end (arg_ptr); } +/* Add the formatted string FORMAT to the debug line *LINE. */ void -_gpgme_debug_add (void **helper, const char *format, ...) +_gpgme_debug_add (void **line, const char *format, ...) { - struct debug_control_s *ctl = *helper; - va_list arg_ptr ; - - if ( !*helper ) - return; - - va_start ( arg_ptr, format ) ; - vfprintf (ctl->fp, format, arg_ptr) ; - va_end ( arg_ptr ) ; + va_list arg_ptr; + char *toadd; + char *result; + + if (!line) + return; + + va_start (arg_ptr, format); + vasprintf (&toadd, format, arg_ptr); + va_end (arg_ptr); + asprintf (&result, "%s%s", *(char **) line, toadd); + free (*line); + free (toadd); + *line = result; } + +/* Finish construction of *LINE and send it to the debug output + stream. */ void -_gpgme_debug_end (void **helper, const char *text) +_gpgme_debug_end (void **line) { - struct debug_control_s *ctl = *helper; - int c, last_c=EOF; - - if ( !*helper ) - return; - - _gpgme_debug_add (helper, "%s", text ); - fflush (ctl->fp); /* we need this for the buggy Windoze libc */ - rewind (ctl->fp); - LOCK (debug_lock); - while ( (c=getc (ctl->fp)) != EOF ) { - putc (c, errfp); - last_c = c; - } - if (last_c != '\n') - putc ('\n', errfp); - UNLOCK (debug_lock); - - fclose (ctl->fp); - remove (ctl->fname); - xfree (ctl); - *helper = NULL; + if (!line) + return; + + /* The smallest possible level is 1, so force logging here by + using that. */ + _gpgme_debug (1, "%s", *line); + free (*line); + *line = NULL; } - diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index 511ab53..be418d2 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -295,15 +295,14 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds) FD_ZERO (&writefds); max_fd = 0; - if (_gpgme_debug_level () > 2) - DEBUG_BEGIN (dbg_help, "gpgme:select on [ "); + DEBUG_BEGIN (dbg_help, 3, "gpgme:select on [ "); any = 0; for (i = 0; i < nfds; i++) { if (fds[i].fd == -1) continue; if (fds[i].frozen) - DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd ); + DEBUG_ADD1 (dbg_help, "f%d ", fds[i].fd); else if (fds[i].for_read) { assert (!FD_ISSET (fds[i].fd, &readfds)); @@ -339,9 +338,8 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds) return -1; /* error */ } - if (_gpgme_debug_level () > 2) - DEBUG_BEGIN (dbg_help, "select OK [ "); - if (DEBUG_ENABLED(dbg_help)) + DEBUG_BEGIN (dbg_help, 3, "select OK [ "); + if (DEBUG_ENABLED (dbg_help)) { for (i = 0; i <= max_fd; i++) { diff --git a/gpgme/util.h b/gpgme/util.h index eeb88e2..d6c193c 100644 --- a/gpgme/util.h +++ b/gpgme/util.h @@ -23,6 +23,7 @@ #define UTIL_H #include "types.h" +#include "debug.h" void *_gpgme_malloc (size_t n ); void *_gpgme_calloc (size_t n, size_t m ); @@ -41,59 +42,6 @@ void _gpgme_free ( void *a ); #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) -#ifndef STR - #define STR(v) #v -#endif -#define STR2(v) STR(v) - - -void _gpgme_debug (int level, const char *format, ...); -int _gpgme_debug_level (void); -void _gpgme_debug_begin ( void **helper, int level, const char *text); -int _gpgme_debug_enabled ( void **helper ); -void _gpgme_debug_add (void **helper, const char *format, ...); -void _gpgme_debug_end (void **helper, const char *text); - -#define DEBUG0(x) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x ) -#define DEBUG1(x,a) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__)": " x, (a) ) -#define DEBUG2(x,a,b) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b) ) -#define DEBUG3(x,a,b,c) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c) ) -#define DEBUG4(x,a,b,c,d) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d) ) -#define DEBUG5(x,a,b,c,d,e) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e) ) -#define DEBUG6(x,a,b,c,d,e,f) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f) ) -#define DEBUG7(x,a,b,c,d,e,f,g) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g) ) -#define DEBUG8(x,a,b,c,d,e,f,g,h) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h) ) -#define DEBUG9(x,a,b,c,d,e,f,g,h,i) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h), (i) ) -#define DEBUG10(x,a,b,c,d,e,f,g,h,i,j) _gpgme_debug (1, __FILE__ ":" \ - STR2 (__LINE__) ": " x, (a), (b), (c), (d), (e), (f), (g), (h), (i), (j) ) - -#define DEBUG_BEGIN(y,x) _gpgme_debug_begin (&(y), 1, __FILE__ ":" \ - STR2 (__LINE__) ": " x ) -#define DEBUG_ENABLED(y) _gpgme_debug_enabled(&(y)) -#define DEBUG_ADD0(y,x) _gpgme_debug_add (&(y), (x), \ - ) -#define DEBUG_ADD1(y,x,a) _gpgme_debug_add (&(y), (x), \ - (a) ) -#define DEBUG_ADD2(y,x,a,b) _gpgme_debug_add (&(y), (x), \ - (a), (b) ) -#define DEBUG_ADD3(y,x,a,b,c) _gpgme_debug_add (&(y), (x), \ - (a), (b), (c) ) -#define DEBUG_ADD4(y,x,a,b,c,d) _gpgme_debug_add (&(y), (x), \ - (a), (b), (c), (d) ) -#define DEBUG_ADD5(y,x,a,b,c,d,e) _gpgme_debug_add (&(y), (x), \ - (a), (b), (c), (d), (e) ) -#define DEBUG_END(y,x) _gpgme_debug_end (&(y), (x) ) - #ifndef HAVE_STPCPY