Improved debug support: Assuan logging is now directed to the gpgme debug

stream.
Create processes detached.
This commit is contained in:
Werner Koch 2007-08-02 14:59:01 +00:00
parent ba87348230
commit 5e00a176f5
11 changed files with 128 additions and 25 deletions

View File

@ -1,3 +1,11 @@
2007-08-02 Werner Koch <wk@g10code.com>
* assuan-pipe-connect.c (pipe_connect_w32): A bit more debug output.
(pipe_connect_w32): Use DETACHED_PROCESS flag.
* assuan-logging.c (log_level): New. Use this to disable logging.
(assuan_set_assuan_log_level): New.
* assuan.h: Add prototype.
2007-07-12 Werner Koch <wk@g10code.com>
* assuan-handler.c (assuan_get_active_fds): Use get_osfhandle for

View File

@ -37,6 +37,23 @@
static char prefix_buffer[80];
static FILE *_assuan_log;
static int full_logging;
static int log_level = 1; /* Defaults to logging enabled. */
/* Set the log level for general assuan commands. 0 is no logging at
all, 1 is the standard logging and the default. Higher leveles may
be defined in the future. Passing a level of -1 will not change
the current log level. Returns previosu log level. */
int
assuan_set_assuan_log_level (int level)
{
int old = log_level;
if (level != -1)
log_level = level;
return old;
}
void
_assuan_set_default_log_stream (FILE *fp)
@ -105,6 +122,9 @@ _assuan_log_printf (const char *format, ...)
FILE *fp;
const char *prf;
int save_errno = errno;
if (!log_level)
return;
fp = assuan_get_assuan_log_stream ();
prf = assuan_get_assuan_log_prefix ();
@ -128,6 +148,9 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
const unsigned char *s;
int n;
if (!log_level)
return;
for (n=length,s=buffer; n; n--, s++)
if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80))
break;
@ -166,11 +189,16 @@ void
_assuan_log_sanitized_string (const char *string)
{
const unsigned char *s = (const unsigned char *) string;
FILE *fp = assuan_get_assuan_log_stream ();
FILE *fp;
if (! *s)
if (!log_level)
return;
if (!*s)
return;
fp = assuan_get_assuan_log_stream ();
#ifdef HAVE_FLOCKFILE
flockfile (fp);
#endif

View File

@ -641,6 +641,9 @@ create_inheritable_pipe (int filedes[2], int for_write)
w = h;
}
_assuan_log_printf ("created pipe: read=%p%s, write=%p%s\n",
r, for_write? " (inherit)":"",
w, for_write? "":" (inherit)");
filedes[0] = handle_to_fd (r);
filedes[1] = handle_to_fd (w);
return 0;
@ -752,6 +755,7 @@ pipe_connect_w32 (assuan_context_t *ctx,
nullfd = CreateFile ("nul", GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
_assuan_log_printf ("created nul device, hd=%p\n", nullfd);
if (nullfd == INVALID_HANDLE_VALUE)
{
_assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1));
@ -772,14 +776,17 @@ pipe_connect_w32 (assuan_context_t *ctx,
/* Note: We inherit all handles flagged as inheritable. This seems
to be a security flaw but there seems to be no way of selecting
handles to inherit. */
/* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */
/* name, cmdline); */
_assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n",
name, cmdline);
_assuan_log_printf (" stdin=%p stdout=%p stderr=%p\n",
si.hStdInput, si.hStdOutput, si.hStdError);
if (!CreateProcess (name, /* Program to start. */
cmdline, /* Command line arguments. */
&sec_attr, /* Process security attributes. */
&sec_attr, /* Thread security attributes. */
TRUE, /* Inherit handles. */
(CREATE_DEFAULT_ERROR_MODE
| DETACHED_PROCESS
| GetPriorityClass (GetCurrentProcess ())
| CREATE_SUSPENDED), /* Creation flags. */
NULL, /* Environment. */
@ -807,13 +814,15 @@ pipe_connect_w32 (assuan_context_t *ctx,
nullfd = INVALID_HANDLE_VALUE;
}
_assuan_log_printf ("closing handles %p and %p\n",
fd_to_handle (rp[1]), fd_to_handle (wp[0]) );
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
/* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
/* " dwProcessID=%d dwThreadId=%d\n", */
/* pi.hProcess, pi.hThread, */
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
_assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p"
" dwProcessID=%d dwThreadId=%d\n",
pi.hProcess, pi.hThread,
(int) pi.dwProcessId, (int) pi.dwThreadId);
ResumeThread (pi.hThread);
CloseHandle (pi.hThread);

View File

@ -137,6 +137,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define assuan_sendfd _ASSUAN_PREFIX(assuan_sendfd)
#define assuan_receivefd _ASSUAN_PREFIX(assuan_receivefd)
#define assuan_set_malloc_hooks _ASSUAN_PREFIX(assuan_set_malloc_hooks)
#define assuan_set_assuan_log_level _ASSUAN_PREFIX(assuan_set_assuan_log_level)
#define assuan_set_log_stream _ASSUAN_PREFIX(assuan_set_log_stream)
#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error)
#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer)
@ -532,6 +533,14 @@ void assuan_set_assuan_err_source (int errsource);
/*-- assuan-logging.c --*/
/* Set the log level for general assuan commands. 0 is no logging at
all, 1 is the standard logging and the default. Higher leveles may
be defined in the future. Passing a level of -1 will not change
the current log level. Returns previous log level. Note, that
this function is not thread-safe and should in general be used
right at startup. */
int assuan_set_assuan_log_level (int level);
/* Set the stream to which assuan should log message not associated
with a context. By default, this is stderr. The default value
will be changed when the first log stream is associated with a

View File

@ -1,3 +1,15 @@
2007-08-02 Werner Koch <wk@g10code.com>
* w32-glib-io.c (_gpgme_io_spawn): Use DETACHED_PROCESS flag.
* w32-io.c (_gpgme_io_spawn): Ditto.
(_gpgme_io_write): Map ERROR_NO_DATA to EPIPE.
* debug.c (_gpgme_debug): Enable assuan logging.
(_gpgme_debug_subsystem_init): New. * version.c
(do_subsystem_inits): Disable assuan logging and initialize de
debug system.
(gpgme_check_version): Do not trace before the subsystems are
initialized.
2007-07-17 Marcus Brinkmann <marcus@g10code.de>
* debug.c:;5B Include <errno.h> and "debug.h".
@ -5394,7 +5406,7 @@
* data.c (gpgme_data_rewind): Allow to rewind data_type_none.
Copyright 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
Copyright 2001,2002,2003,2004,2005,2006,2007 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without

View File

@ -16,8 +16,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#if HAVE_CONFIG_H
#include <config.h>
@ -30,12 +30,16 @@
#include <ctype.h>
#include <errno.h>
#ifndef HAVE_DOSISH_SYSTEM
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
#endif
#include <assert.h>
#ifdef HAVE_ASSUAN_H
#include "assuan.h"
#endif
#include "util.h"
#include "sema.h"
#include "debug.h"
@ -138,11 +142,29 @@ debug_init (void)
}
if (debug_level > 0)
fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
#ifdef HAVE_ASSUAN_H
assuan_set_assuan_log_prefix ("gpgme-assuan");
assuan_set_assuan_log_stream (errfp);
assuan_set_assuan_log_level (debug_level >= 0? debug_level:0);
#endif /* HAVE_ASSUAN_H*/
}
UNLOCK (debug_lock);
}
/* This should be called as soon as the locks are intialized. It is
required so that the assuan logging gets conncted to the gpgme log
stream as early as possible. */
void
_gpgme_debug_subsystem_init (void)
{
debug_init ();
}
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void

View File

@ -50,6 +50,9 @@ _gpgme_debug_srcname (const char *file)
return s? s+1:file;
}
/* Called early to initialize the logging. */
void _gpgme_debug_subsystem_init (void);
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
void _gpgme_debug (int level, const char *format, ...);

View File

@ -16,8 +16,8 @@
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#ifndef GPGME_H
#define GPGME_H

View File

@ -55,18 +55,20 @@ do_subsystem_inits (void)
return;
_gpgme_sema_subsystem_init ();
_gpgme_io_subsystem_init ();
#ifdef HAVE_ASSUAN_H
assuan_set_assuan_log_level (0);
assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME);
#ifdef HAVE_W32_SYSTEM
#endif /*HAVE_ASSUAN_H*/
_gpgme_debug_subsystem_init ();
#if defined(HAVE_W32_SYSTEM) && defined(HAVE_ASSUAN_H)
_gpgme_io_subsystem_init ();
/* We need to make sure that the sockets are initialized. */
{
WSADATA wsadat;
WSAStartup (0x202, &wsadat);
}
#endif /*HAVE_W32_SYSTEM*/
#endif /*HAVE_ASSUAN_H*/
#endif /*HAVE_W32_SYSTEM && HAVE_ASSUAN_H*/
done = 1;
}
@ -170,10 +172,15 @@ _gpgme_compare_versions (const char *my_version,
const char *
gpgme_check_version (const char *req_version)
{
do_subsystem_inits ();
/* Catch-22: We need to get at least the debug subsystem ready
before using the tarce facility. If we won't the tarce would
automagically initialize the debug system with out the locks
being initialized and missing the assuan log level setting. */
TRACE2 (DEBUG_INIT, "gpgme_check_version: ", 0,
"req_version=%s, VERSION=%s", req_version, VERSION);
do_subsystem_inits ();
return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL;
}

View File

@ -522,7 +522,8 @@ _gpgme_io_spawn (const char *path, char **argv,
}
}
cr_flags |= CREATE_SUSPENDED;
cr_flags |= CREATE_SUSPENDED;
cr_flags |= DETACHED_PROCESS;
if (!CreateProcessA (path,
arg_string,
&sec_attr, /* process security attributes */

View File

@ -752,7 +752,10 @@ _gpgme_io_write (int fd, const void *buffer, size_t count)
if (ctx->error)
{
UNLOCK (ctx->mutex);
errno = ctx->error_code;
if (ctx->error_code == ERROR_NO_DATA)
errno = EPIPE;
else
errno = EIO;
return TRACE_SYSRES (-1);
}
@ -1104,6 +1107,7 @@ _gpgme_io_spawn (const char *path, char **argv,
}
cr_flags |= CREATE_SUSPENDED;
cr_flags |= DETACHED_PROCESS;
if (!CreateProcessA (path,
arg_string,
&sec_attr, /* process security attributes */