* 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-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * 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 <wk@gnupg.org>
* engine-gpgsm.c (_gpgme_gpgsm_new): Redirect any gpgsm error
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
-/* 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.
*
#include "util.h"
#include "sema.h"
+\f
+/* 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
- */
+\f
+/* 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);
}
+\f
+/* 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;
}
-
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));
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++)
{
#define UTIL_H
#include "types.h"
+#include "debug.h"
void *_gpgme_malloc (size_t n );
void *_gpgme_calloc (size_t n, size_t m );
#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