[svn] assuan - r309 - in trunk: . doc src
svn author marcus
cvs at cvs.gnupg.org
Fri Oct 16 20:24:47 CEST 2009
Author: marcus
Date: 2009-10-16 20:24:46 +0200 (Fri, 16 Oct 2009)
New Revision: 309
Removed:
trunk/src/assuan-io-pth.c
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/autogen.sh
trunk/configure.ac
trunk/doc/ChangeLog
trunk/doc/assuan.texi
trunk/src/ChangeLog
trunk/src/Makefile.am
trunk/src/assuan-buffer.c
trunk/src/assuan-client.c
trunk/src/assuan-defs.h
trunk/src/assuan-error.c
trunk/src/assuan-handler.c
trunk/src/assuan-inquire.c
trunk/src/assuan-io.c
trunk/src/assuan-listen.c
trunk/src/assuan-pipe-connect.c
trunk/src/assuan-pipe-server.c
trunk/src/assuan-socket-connect.c
trunk/src/assuan-socket-server.c
trunk/src/assuan-socket.c
trunk/src/assuan-uds.c
trunk/src/assuan.c
trunk/src/assuan.h
trunk/src/context.c
trunk/src/conversion.c
trunk/src/debug.h
trunk/src/libassuan-config.in
trunk/src/libassuan.def
trunk/src/libassuan.m4
trunk/src/libassuan.vers
trunk/src/system.c
Log:
2009-10-16 Marcus Brinkmann <marcus at g10code.de>
* autogen.sh: Remove --with-pth-prefix from configure invocation.
* configure.ac (_ASSUAN_IN_LIBASSUAN, PTH_SYSCALL_SOFT): Do not
set anymore.
(GNUPG_PATH_PTH): Don't invoke.
(HAVE_PTH): Remove conditional.
(LIBASSUAN_CONFIG_THREAD_MODULES): Removed.
doc/
2009-10-16 Marcus Brinkmann <marcus at g10code.com>
* assuan.texi: Remove documentation for thread support.
(assuan_pipe_connect_ext): Update prototype.
src/
2009-10-16 Marcus Brinkmann <marcus at g10code.com>
* conversion.c: Do not include <sys/types.h> and <time.h>.
* debug.h (TRACE_BEG6, TRACE4): New macros.
(TRACE_SYSERR): Pass _assuan_trace_context to _assuan_debug.
* context.c (assuan_set_pointer, assuan_get_pointer,
assuan_set_flag, assuan_get_flag, assuan_set_io_monitor,
assuan_set_error): Add trace messages.
* libassuan-config.in, libassuan.m4, Makefile.am: Remove PTH support.
* assuan.h (assuan_msghdr_t): New type.
(ASSUAN_INVALID_PID): New macro.
(ASSUAN_NO_FIXSIGNALS): New flag macro.
(ASSUAN_SYSTEM_HOOKS_VERSION): New macro.
(struct assuan_system_hooks, assuan_system_hooks_t): New types.
(assuan_pipe_connect, assuan_pipe_connect_ext): Don't make ARGV
const for name==NULL operation. Make fd_child_list an array of
assuan_fd_t.
(assuan_sock_init, assuan_sock_deinit, assuan_set_system_hooks,
assuan_ctx_set_system_hooks, __assuan_pipe, __assuan_close,
__assuan_spawn, __assuan_socketpair): New function prototypes.
(_ASSUAN_SYSTEM_PTH_IMPL, ASSUAN_SYSTEM_PTH_DECL,
ASSUAN_SYSTEM_PTH): New macros.
(_assuan_system_pth): New declaration.
* libassuan.vers, libassuan.defs: Add assuan_sock_init,
assuan_sock_deinit, __assuan_pipe, __assuan_close, __assuan_spawn,
__assuan_socketpair, assuan_set_system_hooks,
assuan_ctx_set_system_hooks.
* assuan-defs.h (struct assuan_io): Removed, move members to ...
(struct assuan_context_s): ... this to ENGINE. New flag
no_fixsignals. New member SYSTEM. Remove member IO.
(_assuan_pipe, _assuan_read, _assuan_write, _assuan_recvmsg,
_assuan_sendmsg, _assuan_spawn, _assuan_socketpair,
_assuan_system_hooks, _assuan_system_hooks_copy): New
declarations.
(_assuan_error_is_eagain, _assuan_waitpid, _assuan_usleep,
_assuan_close, _assuan_sock_new, _assuan_sock_connect,
_assuan_sock_bind, _assuan_sock_get_nonce,
_assuan_sock_check_nonce): Add context argument.
(_assuan_io_read, _assuan_io_write, _assuan_simple_sendmsg,
_assuan_simple_recvmsg): Removed.
* context.c (assuan_ctx_set_system_hooks): New function.
* assuan.c (assuan_set_system_hooks): New function.
(assuan_new_ext): Initialize CTX->system.
(assuan_release): Always output trace message.
* assuan-error.c (_assuan_error_is_eagain): Add ctx argument, pass
along to _assuan_usleep.
* assuan-inquire.c assuan-listen.c, assuan-socket-server.c,
assuan-handler.c, assuan-socket-connect.c, assuan-client.c,
assuan-pipe-connect.c, assuan-socket.c: Pass CTX argument to
functions that need it
(_assuan_sock_new, _assuan_sock_check_none, _assuan_close,
_assuan_error_is_eagain and many more).
* assuan-socket-server.c (assuan_init_socket_server_ext): Update
fields in CTX->engine instead of CTX->io.
* assuan-socket-connect (assuan_socket_connect_ext): Likewise.
* assuan-uds.c (uds_reader, uds_writer, uds_sendfd): Use
_assuan_recvmsg and _assuan_sendmsg instead of
_assuan_simple_recvmsg and _assuan_simple_sendmsg respectively.
(_assuan_init_uds_io): Update fields in CTX->engine instead of
CTX->io.
* assuan-buffer.c: Use functions in CTX->engine instead of CTX->io.
* assuan-pipe-server.c (assuan_init_pipe_server): Update
fields in CTX->engine instead of CTX->io.
* system.c: Include <sys/types.h>, <time.h>, <fcntl.h>, and
<windows.h> resp. <sys/wait.h>. Define MAX_OPEN_FDS.
(_assuan_system_hooks_copy, __assuan_usleep, _assuan_usleep,
__assuan_pipe, _assuan_pipe, __assuan_close, _assuan_close,
__assuan_read, _assuan_read, __assuan_write, _assuan_write,
__assuan_recvmsg, _assuan_recvmsg, __assuan_sendmsg,
_assuan_sendmsg, __assuan_spawn, _assuan_spawn, __assuan_waitpid,
_assuan_waitpid, __assuan_socketpair, _assuan_socketpair): New
functions.
(_assuan_system_hooks): New singleton.
* assuan-io.c (_assuan_waitpid, do_io_read, _assuan_io_read,
do_io_write, _assuan_io_write, _assuan_simple_sendmsg,
_assuan_simple_recvmsg, _assuan_usleep): Removed.
* assuan-pipe-connect (writen, build_w32_commandline,
create_inheritable_pipe): Removed (actually moved to system.c).
(fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: Still fix signals.
(do_finish): Move waitpid logic to _assuan_waitpid, just call
that.
(struct at_pipe_fork, struct at_socketpair_fork): New types.
(at_pipe_fork_cb, at_socketpair_fork_cb): New callback functions.
(pipe_connect_unix, pipe_connect_w32): Replaced by ...
(pipe_connect): ... this new function using new system functions.
(socketpair_connect): Reimplement to use new system functions.
(assuan_pipe_connect, assuan_pipe_connect_ext): Add trace message.
* assuan-socket.c (_assuan_close): Removed (moved to system.c).
(_assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind,
_assuan_sock_get_nonce, _assuan_sock_check_nonce): Add context
argument. Use new system interface.
(sock_ctx): New singleton.
(assuan_sock_init, assuan_sock_deinit): New functions to
initialize and deinitialize the singleton.
[The diff below has been truncated]
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/ChangeLog 2009-10-16 18:24:46 UTC (rev 309)
@@ -1,3 +1,12 @@
+2009-10-16 Marcus Brinkmann <marcus at g10code.de>
+
+ * autogen.sh: Remove --with-pth-prefix from configure invocation.
+ * configure.ac (_ASSUAN_IN_LIBASSUAN, PTH_SYSCALL_SOFT): Do not
+ set anymore.
+ (GNUPG_PATH_PTH): Don't invoke.
+ (HAVE_PTH): Remove conditional.
+ (LIBASSUAN_CONFIG_THREAD_MODULES): Removed.
+
2009-10-08 Marcus Brinkmann <marcus at g10code.de>
* configure.ac: AC_REPLACE_FUNCS for vasprintf.
Modified: trunk/doc/ChangeLog
===================================================================
--- trunk/doc/ChangeLog 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/doc/ChangeLog 2009-10-16 18:24:46 UTC (rev 309)
@@ -1,3 +1,8 @@
+2009-10-16 Marcus Brinkmann <marcus at g10code.com>
+
+ * assuan.texi: Remove documentation for thread support.
+ (assuan_pipe_connect_ext): Update prototype.
+
2009-10-14 Werner Koch <wk at g10code.com>
* assuan.texi (Utilities): Describe assuan_get_command_name.
Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/ChangeLog 2009-10-16 18:24:46 UTC (rev 309)
@@ -1,3 +1,105 @@
+2009-10-16 Marcus Brinkmann <marcus at g10code.com>
+
+ * conversion.c: Do not include <sys/types.h> and <time.h>.
+ * debug.h (TRACE_BEG6, TRACE4): New macros.
+ (TRACE_SYSERR): Pass _assuan_trace_context to _assuan_debug.
+ * context.c (assuan_set_pointer, assuan_get_pointer,
+ assuan_set_flag, assuan_get_flag, assuan_set_io_monitor,
+ assuan_set_error): Add trace messages.
+
+ * libassuan-config.in, libassuan.m4, Makefile.am: Remove PTH support.
+ * assuan.h (assuan_msghdr_t): New type.
+ (ASSUAN_INVALID_PID): New macro.
+ (ASSUAN_NO_FIXSIGNALS): New flag macro.
+ (ASSUAN_SYSTEM_HOOKS_VERSION): New macro.
+ (struct assuan_system_hooks, assuan_system_hooks_t): New types.
+ (assuan_pipe_connect, assuan_pipe_connect_ext): Don't make ARGV
+ const for name==NULL operation. Make fd_child_list an array of
+ assuan_fd_t.
+ (assuan_sock_init, assuan_sock_deinit, assuan_set_system_hooks,
+ assuan_ctx_set_system_hooks, __assuan_pipe, __assuan_close,
+ __assuan_spawn, __assuan_socketpair): New function prototypes.
+ (_ASSUAN_SYSTEM_PTH_IMPL, ASSUAN_SYSTEM_PTH_DECL,
+ ASSUAN_SYSTEM_PTH): New macros.
+ (_assuan_system_pth): New declaration.
+ * libassuan.vers, libassuan.defs: Add assuan_sock_init,
+ assuan_sock_deinit, __assuan_pipe, __assuan_close, __assuan_spawn,
+ __assuan_socketpair, assuan_set_system_hooks,
+ assuan_ctx_set_system_hooks.
+
+ * assuan-defs.h (struct assuan_io): Removed, move members to ...
+ (struct assuan_context_s): ... this to ENGINE. New flag
+ no_fixsignals. New member SYSTEM. Remove member IO.
+ (_assuan_pipe, _assuan_read, _assuan_write, _assuan_recvmsg,
+ _assuan_sendmsg, _assuan_spawn, _assuan_socketpair,
+ _assuan_system_hooks, _assuan_system_hooks_copy): New
+ declarations.
+ (_assuan_error_is_eagain, _assuan_waitpid, _assuan_usleep,
+ _assuan_close, _assuan_sock_new, _assuan_sock_connect,
+ _assuan_sock_bind, _assuan_sock_get_nonce,
+ _assuan_sock_check_nonce): Add context argument.
+ (_assuan_io_read, _assuan_io_write, _assuan_simple_sendmsg,
+ _assuan_simple_recvmsg): Removed.
+
+ * context.c (assuan_ctx_set_system_hooks): New function.
+ * assuan.c (assuan_set_system_hooks): New function.
+ (assuan_new_ext): Initialize CTX->system.
+ (assuan_release): Always output trace message.
+
+ * assuan-error.c (_assuan_error_is_eagain): Add ctx argument, pass
+ along to _assuan_usleep.
+ * assuan-inquire.c assuan-listen.c, assuan-socket-server.c,
+ assuan-handler.c, assuan-socket-connect.c, assuan-client.c,
+ assuan-pipe-connect.c, assuan-socket.c: Pass CTX argument to
+ functions that need it
+ (_assuan_sock_new, _assuan_sock_check_none, _assuan_close,
+ _assuan_error_is_eagain and many more).
+ * assuan-socket-server.c (assuan_init_socket_server_ext): Update
+ fields in CTX->engine instead of CTX->io.
+ * assuan-socket-connect (assuan_socket_connect_ext): Likewise.
+ * assuan-uds.c (uds_reader, uds_writer, uds_sendfd): Use
+ _assuan_recvmsg and _assuan_sendmsg instead of
+ _assuan_simple_recvmsg and _assuan_simple_sendmsg respectively.
+ (_assuan_init_uds_io): Update fields in CTX->engine instead of
+ CTX->io.
+ * assuan-buffer.c: Use functions in CTX->engine instead of CTX->io.
+ * assuan-pipe-server.c (assuan_init_pipe_server): Update
+ fields in CTX->engine instead of CTX->io.
+
+ * system.c: Include <sys/types.h>, <time.h>, <fcntl.h>, and
+ <windows.h> resp. <sys/wait.h>. Define MAX_OPEN_FDS.
+ (_assuan_system_hooks_copy, __assuan_usleep, _assuan_usleep,
+ __assuan_pipe, _assuan_pipe, __assuan_close, _assuan_close,
+ __assuan_read, _assuan_read, __assuan_write, _assuan_write,
+ __assuan_recvmsg, _assuan_recvmsg, __assuan_sendmsg,
+ _assuan_sendmsg, __assuan_spawn, _assuan_spawn, __assuan_waitpid,
+ _assuan_waitpid, __assuan_socketpair, _assuan_socketpair): New
+ functions.
+ (_assuan_system_hooks): New singleton.
+ * assuan-io.c (_assuan_waitpid, do_io_read, _assuan_io_read,
+ do_io_write, _assuan_io_write, _assuan_simple_sendmsg,
+ _assuan_simple_recvmsg, _assuan_usleep): Removed.
+
+ * assuan-pipe-connect (writen, build_w32_commandline,
+ create_inheritable_pipe): Removed (actually moved to system.c).
+ (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: Still fix signals.
+ (do_finish): Move waitpid logic to _assuan_waitpid, just call
+ that.
+ (struct at_pipe_fork, struct at_socketpair_fork): New types.
+ (at_pipe_fork_cb, at_socketpair_fork_cb): New callback functions.
+ (pipe_connect_unix, pipe_connect_w32): Replaced by ...
+ (pipe_connect): ... this new function using new system functions.
+ (socketpair_connect): Reimplement to use new system functions.
+ (assuan_pipe_connect, assuan_pipe_connect_ext): Add trace message.
+
+ * assuan-socket.c (_assuan_close): Removed (moved to system.c).
+ (_assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind,
+ _assuan_sock_get_nonce, _assuan_sock_check_nonce): Add context
+ argument. Use new system interface.
+ (sock_ctx): New singleton.
+ (assuan_sock_init, assuan_sock_deinit): New functions to
+ initialize and deinitialize the singleton.
+
2009-10-14 Werner Koch <wk at g10code.com>
* assuan-defs.h (assuan_context_s): Add field CURRENT_CMD_NAME.
@@ -7,6 +109,18 @@
2009-10-08 Marcus Brinkmann <marcus at g10code.de>
+ * Makefile.am (libassuan_pth): Removed.
+ (lib_LTLIBRARIES): Remove $(libassuan_pth).
+ (libassuan_pth_la_SOURCES, libassuan_pth_la_CPPFLAGS)
+ (libassuan_pth_la_CFLAGS, libassuan_pth_la_LIBADD): Removed.
+ * libassuan.m4 (AM_PATH_LIBASSUAN_PTH, AM_PATH_LIBASSUAN_PTHREAD):
+ Removed.
+ * assuan-io-pth.c: Removed.
+ * libassuan-config.in (all_thread_modules): Removed. Also removed
+ option --thread.
+
+2009-10-08 Marcus Brinkmann <marcus at g10code.de>
+
* assuan.h (assuan_get_assuan_log_stream,
assuan_set_assuan_log_stream): Remove prototypes.
* libassuan.def: Remove assuan_get_assuan_log_stream,
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/NEWS 2009-10-16 18:24:46 UTC (rev 309)
@@ -13,8 +13,12 @@
If you use assuan_pipe_connect or assuan_pipe_connect_ext with NAME
of NULL, you have to provide a non-NULL ARGV argument and check
that against "server" or "client" to determine which end you got
- after fork().
+ after fork(). If you use the assuan sock interface, you must call
+ assuan_sock_init after setting global context defaults.
+ * Pth support has changed. This now follows the same style as
+ libgcrypt by setting system hook callbacks.
+
* Interface changes relative to the 1.0.5 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_ASSUAN_ONLY_GPG_ERRORS REMOVED
@@ -51,6 +55,18 @@
assuan_io_hooks_t REMOVED: Will come back in expanded form.
assuan_io_monitor_t CHANGED: Add a hook data argument.
assuan_get_command_name NEW
+assuan_msghdr_t NEW
+ASSUAN_INVALID_PID NEW
+ASSUAN_NO_FIXSIGNALS NEW
+ASSUAN_SYSTEM_HOOKS_VERSION NEW
+assuan_system_hooks_t NEW
+assuan_set_system_hooks NEW
+assuan_ctx_set_system_hooks NEW
+ASSUAN_SYSTEM_PTH_IMPL NEW
+ASSUAN_SYSTEM_PTH_DECL NEW
+ASSUAN_SYSTEM_PTH NEW
+assuan_sock_init NEW
+assuan_sock_deinit NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/autogen.sh
===================================================================
--- trunk/autogen.sh 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/autogen.sh 2009-10-16 18:24:46 UTC (rev 309)
@@ -77,7 +77,6 @@
./configure --enable-maintainer-mode --prefix=${w32root} \
--host=${host} --build=${build} \
- --with-pth-prefix=${w32root} \
--disable-shared
exit $?
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/configure.ac 2009-10-16 18:24:46 UTC (rev 309)
@@ -1,5 +1,5 @@
# configure.ac - for libassuan
-# Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2001-2003, 2006, 2007, 2009 Free Software Foundation, Inc.
#
# This file is part of Assuan.
#
@@ -132,16 +132,6 @@
fi
-AH_BOTTOM([
-#define _ASSUAN_IN_LIBASSUAN 1
-
-/* We explicitly need to disable PTH's soft mapping as Debian
- currently enables it by default for no reason. */
-#define PTH_SYSCALL_SOFT 0
-
-])
-
-
#
# Options depending on the host OS.
#
@@ -191,13 +181,7 @@
AC_SUBST(BUILD_FILEVERSION)
AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
-#
-# See whether we can build a Pth enabled version
-#
-GNUPG_PATH_PTH
-AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
-
# Check for network libraries. They are needed for tests.
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt,
[NETLIBS="-lsocket $NETLIBS"]))
@@ -211,10 +195,6 @@
# For src/libassuan-config.in
LIBASSUAN_CONFIG_LIB="-lassuan"
LIBASSUAN_CONFIG_CFLAGS=""
-LIBASSUAN_CONFIG_THREAD_MODULES=
-if test "$have_pth" = yes; then
-LIBASSUAN_CONFIG_THREAD_MODULES="pth"
-fi
LIBASSUAN_CONFIG_EXTRA_LIBS=
if test x"$NETLIBS" != x; then
LIBASSUAN_CONFIG_EXTRA_LIBS="$LIBASSUAN_CONFIG_EXTRA_LIBS $NETLIBS"
@@ -222,7 +202,6 @@
AC_SUBST(LIBASSUAN_CONFIG_LIB)
AC_SUBST(LIBASSUAN_CONFIG_CFLAGS)
AC_SUBST(LIBASSUAN_CONFIG_API_VERSION)
-AC_SUBST(LIBASSUAN_CONFIG_THREAD_MODULES)
AC_SUBST(LIBASSUAN_CONFIG_EXTRA_LIBS)
# Checks for header files.
Modified: trunk/doc/assuan.texi
===================================================================
--- trunk/doc/assuan.texi 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/doc/assuan.texi 2009-10-16 18:24:46 UTC (rev 309)
@@ -465,11 +465,7 @@
gcc -o foo foo.c $(libassuan-config --cflags --libs)
@end example
-If your application uses Pth or pthread, you need to pass the option
- at option{--thread=pth} respective @option{--thread=pthread} to the
-invocation of @command{libassuan-config}.
-
@node Automake
@section Building sources using Automake
@@ -498,36 +494,27 @@
LDADD = $(LIBASSUAN_LIBS)
@end example
- at defmac AM_PATH_LIBASSUAN_PTH (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found})
-Same as @code{AM_PATH_LIBASSUAN} but checks for the GNU Pth enabled
-version of the library and defines @code{LIBASSUAN_PTH_CFLAGS}
- at code{LIBASSUAN_PTH_LIBS} instead. Use this is you are using GNU Pth.
-Note that you also need to pass the appropriate options for Pth to the
-compiler and linker.
- at end defmac
- at defmac AM_PATH_LIBASSUAN_PTHREAD (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found})
-Same as @code{AM_PATH_LIBASSUAN} but checks for the pthreads enabled
-version of the library and defines @code{LIBASSUAN_PTHREAD_CFLAGS}
- at code{LIBASSUAN_PTHREAD_LIBS} instead. Use this is you are using GNU Pth.
-Note that you also need to pass the appropriate options for Pth to the
-compiler and linker.
- at end defmac
-
-
-
@node Multi Threading
@section Multi Threading
-The @code{libassuan} library is thread-safe if you adhere to the following
-requirements:
+The @code{libassuan} library is designed so that it can be used in a
+threaded application, if some rules are followed.
@itemize @bullet
@item Run the initialization functions before you actually start
-to use threads.
+to use threads. Specifically, the functions
+ at code{assuan_set_gpg_err_source}, @code{assuan_set_malloc_hooks} and
+ at code{assuan_set_log_cb} should not be called concurrently with
+ at code{assuan_new}. Use @code{assuan_new_ext} instead or ensure proper
+serialization.
@item Only one thread at a time may access an @code{libassuan} context.
@item If you use the default log handler, use
@code{assuan_set_assuan_log_stream} to setup a default log stream.
+ at item If you have callback functions shared by multiple functions,
+the callback function must be reentrant for that purpose.
+ at code{libassuan} does not serialize invocation of callback functions
+across contexts.
@end itemize
@@ -950,12 +937,12 @@
sockets, the full-fledged variant of the above function should be
used:
- at deftypefun gpg_error_t assuan_pipe_connect_ext (@w{assuan_context_t *@var{ctx}}, at w{const char *@var{name}}, @w{const char *@var{argv}[]}, @w{int *@var{fd_child_list}}, @w{void (*@var{atfork}) (void *, int)}, @w{void *@var{atforkvalue}}, @w{unsigned int @var{flags}})
+ at deftypefun gpg_error_t assuan_pipe_connect_ext (@w{assuan_context_t *@var{ctx}}, at w{const char *@var{name}}, @w{const char *@var{argv}[]}, @w{assuan_fd_t *@var{fd_child_list}}, @w{void (*@var{atfork}) (void *, int)}, @w{void *@var{atforkvalue}}, @w{unsigned int @var{flags}})
A call to this functions forks the current process and executes the
program @var{name}, passing the arguments given in the NULL-terminated
list @var{argv}. A list of file descriptors not to be closed may be
-given using the @code{-1} terminated array @var{fd_child_list}.
+given using the @code{ASSUAN_INVLID_FD} terminated array @var{fd_child_list}.
If @var{name} is a null pointer, only a fork but no exec is done.
Thus the child continues to run. However all file descriptors are
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/Makefile.am 2009-10-16 18:24:46 UTC (rev 309)
@@ -21,16 +21,10 @@
versioninfo.rc.in libassuan.def
INCLUDES = -I.. -I$(top_srcdir)/include
-if HAVE_PTH
-libassuan_pth = libassuan-pth.la
-else
-libassuan_pth =
-endif
-
bin_SCRIPTS = libassuan-config
m4datadir = $(datadir)/aclocal
m4data_DATA = libassuan.m4
-lib_LTLIBRARIES = libassuan.la $(libassuan_pth)
+lib_LTLIBRARIES = libassuan.la
include_HEADERS = assuan.h
if HAVE_LD_VERSION_SCRIPT
@@ -107,11 +101,3 @@
libassuan_la_DEPENDENCIES = @LTLIBOBJS@ \
$(srcdir)/libassuan.vers $(libassuan_deps)
libassuan_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@
-
-if HAVE_PTH
-libassuan_pth_la_SOURCES = $(common_sources) assuan-io-pth.c
-libassuan_pth_la_CPPFLAGS = $(AM_CPPFLAGS) @GPG_ERROR_CFLAGS@ @PTH_CFLAGS@
-libassuan_pth_la_CFLAGS = $(AM_CFLAGS) @GPG_ERROR_CFLAGS@ $(PTH_CFLAGS)
-libassuan_pth_la_LIBADD = @LTLIBOBJS@ @NETLIBS@ @GPG_ERROR_LIBS@ @PTH_LIBS@
-endif
-
Modified: trunk/src/assuan-buffer.c
===================================================================
--- trunk/src/assuan-buffer.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-buffer.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -37,7 +37,7 @@
{
while (length)
{
- ssize_t nwritten = ctx->io->writefnc (ctx, buffer, length);
+ ssize_t nwritten = ctx->engine.writefnc (ctx, buffer, length);
if (nwritten < 0)
{
@@ -66,7 +66,7 @@
*r_nread = 0;
while (nleft > 0)
{
- ssize_t n = ctx->io->readfnc (ctx, buf, nleft);
+ ssize_t n = ctx->engine.readfnc (ctx, buf, nleft);
if (n < 0)
{
@@ -249,7 +249,7 @@
{
err = _assuan_read_line (ctx);
}
- while (_assuan_error_is_eagain (err));
+ while (_assuan_error_is_eagain (ctx, err));
*line = ctx->inbound.line;
*linelen = ctx->inbound.linelen;
@@ -551,19 +551,19 @@
return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED);
#endif
- if (! ctx->io->sendfd)
+ if (! ctx->engine.sendfd)
return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED,
"server does not support sending and receiving "
"of file descriptors");
- return ctx->io->sendfd (ctx, fd);
+ return ctx->engine.sendfd (ctx, fd);
}
gpg_error_t
assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
{
- if (! ctx->io->receivefd)
+ if (! ctx->engine.receivefd)
return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED,
"server does not support sending and receiving "
"of file descriptors");
- return ctx->io->receivefd (ctx, fd);
+ return ctx->engine.receivefd (ctx, fd);
}
Modified: trunk/src/assuan-client.c
===================================================================
--- trunk/src/assuan-client.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-client.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -49,7 +49,7 @@
{
rc = _assuan_read_line (ctx);
}
- while (_assuan_error_is_eagain (rc));
+ while (_assuan_error_is_eagain (ctx, rc));
if (rc)
return rc;
line = ctx->inbound.line;
Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-defs.h 2009-10-16 18:24:46 UTC (rev 309)
@@ -56,19 +56,6 @@
};
-/* A structure to dispatch I/O functions. */
-struct assuan_io
-{
- /* Routine to read from input_fd. Sets errno on failure. */
- ssize_t (*readfnc) (assuan_context_t, void *, size_t);
- /* Routine to write to output_fd. Sets errno on failure. */
- ssize_t (*writefnc) (assuan_context_t, const void *, size_t);
- /* Send a file descriptor. */
- gpg_error_t (*sendfd) (assuan_context_t, assuan_fd_t);
- /* Receive a file descriptor. */
- gpg_error_t (*receivefd) (assuan_context_t, assuan_fd_t *);
-};
-
/* The context we use with most functions. */
struct assuan_context_s
@@ -97,17 +84,30 @@
{
unsigned int no_waitpid : 1;
unsigned int confidential : 1;
+ unsigned int no_fixsignals : 1;
} flags;
/* If set, this is called right before logging an I/O line. */
assuan_io_monitor_t io_monitor;
void *io_monitor_data;
+ /* Callback handlers replacing system I/O functions. */
+ struct assuan_system_hooks system;
+
/* Now come the members specific to subsystems or engines. FIXME:
This is not developed yet. See below for the legacy members. */
struct
{
void (*release) (assuan_context_t ctx);
+
+ /* Routine to read from input_fd. Sets errno on failure. */
+ ssize_t (*readfnc) (assuan_context_t, void *, size_t);
+ /* Routine to write to output_fd. Sets errno on failure. */
+ ssize_t (*writefnc) (assuan_context_t, const void *, size_t);
+ /* Send a file descriptor. */
+ gpg_error_t (*sendfd) (assuan_context_t, assuan_fd_t);
+ /* Receive a file descriptor. */
+ gpg_error_t (*receivefd) (assuan_context_t, assuan_fd_t *);
} engine;
@@ -220,11 +220,6 @@
assuan_fd_t input_fd; /* Set by the INPUT command. */
assuan_fd_t output_fd; /* Set by the OUTPUT command. */
-
- /* io routines. */
- struct assuan_io *io;
-
-
};
@@ -242,6 +237,38 @@
void *_assuan_calloc (assuan_context_t ctx, size_t cnt, size_t elsize);
void _assuan_free (assuan_context_t ctx, void *ptr);
+/* System hooks. */
+void _assuan_usleep (assuan_context_t ctx, unsigned int usec);
+int _assuan_pipe (assuan_context_t ctx, assuan_fd_t fd[2], int inherit_idx);
+int _assuan_close (assuan_context_t ctx, assuan_fd_t fd);
+ssize_t _assuan_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer,
+ size_t size);
+ssize_t _assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer,
+ size_t size);
+int _assuan_recvmsg (assuan_context_t ctx, assuan_fd_t fd,
+ assuan_msghdr_t msg, int flags);
+int _assuan_sendmsg (assuan_context_t ctx, assuan_fd_t fd,
+ assuan_msghdr_t msg, int flags);
+int _assuan_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
+ const char *argv[],
+ assuan_fd_t fd_in, assuan_fd_t fd_out,
+ assuan_fd_t *fd_child_list,
+ void (*atfork) (void *opaque, int reserved),
+ void *atforkvalue, unsigned int flags);
+pid_t _assuan_waitpid (assuan_context_t ctx, pid_t pid, int nowait,
+ int *status, int options);
+int _assuan_socketpair (assuan_context_t ctx, int namespace, int style,
+ int protocol, int filedes[2]);
+
+extern struct assuan_system_hooks _assuan_system_hooks;
+
+/* Copy the system hooks struct, paying attention to version
+ differences. SRC is usually from the user, DST MUST be from the
+ library. */
+void
+_assuan_system_hooks_copy (assuan_system_hooks_t dst,
+ assuan_system_hooks_t src);
+
/*-- assuan-pipe-server.c --*/
void _assuan_release_context (assuan_context_t ctx);
@@ -273,7 +300,7 @@
void _assuan_inquire_release (assuan_context_t ctx);
/* Check if ERR means EAGAIN. */
-int _assuan_error_is_eagain (gpg_error_t err);
+int _assuan_error_is_eagain (assuan_context_t ctx, gpg_error_t err);
@@ -290,33 +317,22 @@
/*-- assuan-io.c --*/
-pid_t _assuan_waitpid (pid_t pid, int *status, int options);
-
ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size);
ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer,
size_t size);
-ssize_t _assuan_io_read (assuan_fd_t fd, void *buffer, size_t size);
-ssize_t _assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size);
-#ifdef HAVE_W32_SYSTEM
-int _assuan_simple_sendmsg (assuan_context_t ctx, void *msg);
-int _assuan_simple_recvmsg (assuan_context_t ctx, void *msg);
-#else
-ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg);
-ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg);
-#endif
-void _assuan_usleep (unsigned int usec);
+/*-- assuan-socket.c --*/
-
-/*-- assuan-socket.c --*/
-int _assuan_close (assuan_fd_t fd);
-assuan_fd_t _assuan_sock_new (int domain, int type, int proto);
-int _assuan_sock_connect (assuan_fd_t sockfd,
+assuan_fd_t _assuan_sock_new (assuan_context_t ctx, int domain, int type,
+ int proto);
+int _assuan_sock_connect (assuan_context_t ctx, assuan_fd_t sockfd,
struct sockaddr *addr, int addrlen);
-int _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
-int _assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
- assuan_sock_nonce_t *nonce);
-int _assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
+int _assuan_sock_bind (assuan_context_t ctx, assuan_fd_t sockfd,
+ struct sockaddr *addr, int addrlen);
+int _assuan_sock_get_nonce (assuan_context_t ctx, struct sockaddr *addr,
+ int addrlen, assuan_sock_nonce_t *nonce);
+int _assuan_sock_check_nonce (assuan_context_t ctx, assuan_fd_t fd,
+ assuan_sock_nonce_t *nonce);
#ifdef HAVE_W32_SYSTEM
int _assuan_sock_wsa2errno (int err);
#endif
Modified: trunk/src/assuan-error.c
===================================================================
--- trunk/src/assuan-error.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-error.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -33,13 +33,13 @@
/* A small helper function to treat EAGAIN transparently to the
caller. */
int
-_assuan_error_is_eagain (gpg_error_t err)
+_assuan_error_is_eagain (assuan_context_t ctx, gpg_error_t err)
{
if (gpg_err_code (err) == GPG_ERR_EAGAIN)
{
/* Avoid spinning by sleeping for one tenth of a second. */
- _assuan_usleep (100000);
- return 1;
+ _assuan_usleep (ctx, 100000);
+ return 1;
}
else
return 0;
Modified: trunk/src/assuan-handler.c
===================================================================
--- trunk/src/assuan-handler.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-handler.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -219,6 +219,7 @@
return PROCESS_DONE (ctx, 0);
}
+
/* Format is OUTPUT FD=<n> */
static gpg_error_t
std_handler_output (assuan_context_t ctx, char *line)
@@ -236,9 +237,6 @@
}
-
-
-
/* This is a table with the standard commands and handler for them.
The table is used to initialize a new context and associate strings
with default handlers */
@@ -592,7 +590,7 @@
required to write full lines without blocking long after starting
a partial line. */
rc = _assuan_read_line (ctx);
- if (_assuan_error_is_eagain (rc))
+ if (_assuan_error_is_eagain (ctx, rc))
return 0;
if (rc)
return rc;
@@ -670,7 +668,7 @@
{
rc = _assuan_read_line (ctx);
}
- while (_assuan_error_is_eagain (rc));
+ while (_assuan_error_is_eagain (ctx, rc));
if (rc)
return rc;
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
Modified: trunk/src/assuan-inquire.c
===================================================================
--- trunk/src/assuan-inquire.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-inquire.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -176,7 +176,7 @@
{
do
rc = _assuan_read_line (ctx);
- while (_assuan_error_is_eagain (rc));
+ while (_assuan_error_is_eagain (ctx, rc));
if (rc)
goto leave;
line = (unsigned char *) ctx->inbound.line;
Deleted: trunk/src/assuan-io-pth.c
Modified: trunk/src/assuan-io.c
===================================================================
--- trunk/src/assuan-io.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-io.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -38,185 +38,15 @@
#include "assuan-defs.h"
-#ifndef HAVE_W32_SYSTEM
-pid_t
-_assuan_waitpid (pid_t pid, int *status, int options)
-{
- return waitpid (pid, status, options);
-}
-#endif
-
-
-static ssize_t
-do_io_read (assuan_fd_t fd, void *buffer, size_t size)
-{
-#ifdef HAVE_W32_SYSTEM
- /* Due to the peculiarities of the W32 API we can't use read for a
- network socket and thus we try to use recv first and fallback to
- read if recv detects that it is not a network socket. */
- int n;
-
- n = recv (HANDLE2SOCKET(fd), buffer, size, 0);
- if (n == -1)
- {
- switch (WSAGetLastError ())
- {
- case WSAENOTSOCK:
- {
- DWORD nread = 0;
-
- n = ReadFile (fd, buffer, size, &nread, NULL);
- if (!n)
- {
- switch (GetLastError())
- {
- case ERROR_BROKEN_PIPE: errno = EPIPE; break;
- default: errno = EIO;
- }
- n = -1;
- }
- else
- n = (int)nread;
- }
- break;
-
- case WSAEWOULDBLOCK: errno = EAGAIN; break;
- case ERROR_BROKEN_PIPE: errno = EPIPE; break;
- default: errno = EIO; break;
- }
- }
- return n;
-#else /*!HAVE_W32_SYSTEM*/
- return read (fd, buffer, size);
-#endif /*!HAVE_W32_SYSTEM*/
-}
-
-
ssize_t
-_assuan_io_read (assuan_fd_t fd, void *buffer, size_t size)
-{
- return do_io_read (fd, buffer, size);
-}
-
-ssize_t
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
{
- return do_io_read (ctx->inbound.fd, buffer, size);
+ return _assuan_read (ctx, ctx->inbound.fd, buffer, size);
}
-
-static ssize_t
-do_io_write (assuan_fd_t fd, const void *buffer, size_t size)
-{
-#ifdef HAVE_W32_SYSTEM
- /* Due to the peculiarities of the W32 API we can't use write for a
- network socket and thus we try to use send first and fallback to
- write if send detects that it is not a network socket. */
- int n;
-
- n = send (HANDLE2SOCKET(fd), buffer, size, 0);
- if (n == -1 && WSAGetLastError () == WSAENOTSOCK)
- {
- DWORD nwrite;
-
- n = WriteFile (fd, buffer, size, &nwrite, NULL);
- if (!n)
- {
- switch (GetLastError ())
- {
- case ERROR_BROKEN_PIPE:
- case ERROR_NO_DATA: errno = EPIPE; break;
- default: errno = EIO; break;
- }
- n = -1;
- }
- else
- n = (int)nwrite;
- }
- return n;
-#else /*!HAVE_W32_SYSTEM*/
- return write (fd, buffer, size);
-#endif /*!HAVE_W32_SYSTEM*/
-}
-
ssize_t
-_assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size)
-{
- return do_io_write (fd, buffer, size);
-}
-
-ssize_t
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
{
- return do_io_write (ctx->outbound.fd, buffer, size);
+ return _assuan_write (ctx, ctx->outbound.fd, buffer, size);
}
-
-
-#ifdef HAVE_W32_SYSTEM
-int
-_assuan_simple_sendmsg (assuan_context_t ctx, void *msg)
-#else
-ssize_t
-_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg)
-#endif
-{
-#ifdef HAVE_W32_SYSTEM
- errno = ENOSYS;
- return -1;
-#else
- int ret;
- while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR)
- ;
- return ret;
-#endif
-}
-
-
-#ifdef HAVE_W32_SYSTEM
-int
-_assuan_simple_recvmsg (assuan_context_t ctx, void *msg)
-#else
-ssize_t
-_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg)
-#endif
-{
-#ifdef HAVE_W32_SYSTEM
- errno = ENOSYS;
- return -1;
-#else
- int ret;
- while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR)
- ;
- return ret;
-#endif
-}
-
-
-void
-_assuan_usleep (unsigned int usec)
-{
- if (usec)
- {
-#ifdef HAVE_NANOSLEEP
- struct timespec req;
- struct timespec rem;
-
- req.tv_sec = 0;
- req.tv_nsec = usec * 1000;
-
- while (nanosleep (&req, &rem) < 0 && errno == EINTR)
- req = rem;
-
-#elif defined(HAVE_W32_SYSTEM)
- Sleep (usec / 1000);
-#else
- struct timeval tv;
-
- tv.tv_sec = usec / 1000000;
- tv.tv_usec = usec % 1000000;
- select (0, NULL, NULL, NULL, &tv);
-#endif
- }
-}
-
Modified: trunk/src/assuan-listen.c
===================================================================
--- trunk/src/assuan-listen.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-listen.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -138,7 +138,7 @@
{
if (!ctx || ctx->input_fd == ASSUAN_INVALID_FD)
return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
- _assuan_close (ctx->input_fd);
+ _assuan_close (ctx, ctx->input_fd);
ctx->input_fd = ASSUAN_INVALID_FD;
return 0;
}
@@ -151,7 +151,7 @@
if (!ctx || ctx->output_fd == ASSUAN_INVALID_FD)
return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
- _assuan_close (ctx->output_fd);
+ _assuan_close (ctx, ctx->output_fd);
ctx->output_fd = ASSUAN_INVALID_FD;
return 0;
}
Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c 2009-10-14 11:27:08 UTC (rev 308)
+++ trunk/src/assuan-pipe-connect.c 2009-10-16 18:24:46 UTC (rev 309)
@@ -62,7 +62,6 @@
static void
fix_signals (void)
{
-#ifndef _ASSUAN_NO_FIXED_SIGNALS
#ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */
static int fixed_signals;
@@ -82,58 +81,28 @@
/* FIXME: This is not MT safe */
}
#endif /*HAVE_DOSISH_SYSTEM*/
-#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/
}
-#ifndef HAVE_W32_SYSTEM
-static int
-writen (int fd, const char *buffer, size_t length)
-{
- while (length)
- {
- int nwritten = write (fd, buffer, length);
-
- if (nwritten < 0)
- {
- if (errno == EINTR)
- continue;
- return -1; /* write error */
- }
- length -= nwritten;
- buffer += nwritten;
- }
- return 0; /* okay */
-}
-#endif
-
static void
do_finish (assuan_context_t ctx)
{
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
{
- _assuan_close (ctx->inbound.fd);
+ _assuan_close (ctx, ctx->inbound.fd);
if (ctx->inbound.fd == ctx->outbound.fd)
ctx->outbound.fd = ASSUAN_INVALID_FD;
ctx->inbound.fd = ASSUAN_INVALID_FD;
}
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
{
- _assuan_close (ctx->outbound.fd);
+ _assuan_close (ctx, ctx->outbound.fd);
ctx->outbound.fd = ASSUAN_INVALID_FD;
}
- if (ctx->pid != (pid_t)(-1) && ctx->pid)
+ if (ctx->pid != ASSUAN_INVALID_PID && ctx->pid)
{
-#ifndef HAVE_W32_SYSTEM
-#ifndef _ASSUAN_USE_DOUBLE_FORK
- if (!ctx->flags.no_waitpid)
- _assuan_waitpid (ctx->pid, NULL, 0);
- ctx->pid =(pid_t)(-1);
-#endif
-#else /*!HAVE_W32_SYSTEM*/
- CloseHandle ((HANDLE) ctx->pid);
- ctx->pid = (pid_t) INVALID_HANDLE_VALUE;
-#endif /*HAVE_W32_SYSTEM*/
+ _assuan_waitpid (ctx, ctx->pid, ctx->flags.no_waitpid, NULL, 0);
+ ctx->pid = ASSUAN_INVALID_PID;
}
}
@@ -166,178 +135,96 @@
return err;
}
+
+struct at_pipe_fork
+{
+ void (*user_atfork) (void *opaque, int reserved);
+ void *user_atforkvalue;
+};
+
+static void
+at_pipe_fork_cb (void *opaque, int reserved)
+{
+ struct at_pipe_fork *atp = opaque;
+
+ if (atp->user_atfork)
+ atp->user_atfork (atp->user_atforkvalue, reserved);
+
#ifndef HAVE_W32_SYSTEM
-#define pipe_connect pipe_connect_unix
-/* Unix version of the pipe connection code. We use an extra macro to
- make ChangeLog entries easier. */
+ {
+ char mypidstr[50];
+
+ /* We store our parents pid in the environment so that the execed
+ assuan server is able to read the actual pid of the client.
+ The server can't use getppid because it might have been double
+ forked before the assuan server has been initialized. */
+ sprintf (mypidstr, "%lu", (unsigned long) getpid ());
+ setenv ("_assuan_pipe_connect_pid", mypidstr, 1);
+
+ /* Make sure that we never pass a connection fd variable when
+ using a simple pipe. */
+ unsetenv ("_assuan_connection_fd");
+ }
+#endif
+}
+
+
static gpg_error_t
-pipe_connect_unix (assuan_context_t ctx,
- const char *name, const char *const argv[],
- int *fd_child_list,
- void (*atfork) (void *opaque, int reserved),
- void *atforkvalue, unsigned int flags)
+pipe_connect (assuan_context_t ctx,
+ const char *name, const char **argv,
+ int *fd_child_list,
+ void (*atfork) (void *opaque, int reserved),
+ void *atforkvalue, unsigned int flags)
{
- int rp[2];
- int wp[2];
- pid_t pid;
- char mypidstr[50];
gpg_error_t rc;
- static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
- 0, 0 };
+ assuan_fd_t rp[2];
+ assuan_fd_t wp[2];
+ pid_t pid;
+ int res;
+ struct at_pipe_fork atp;
- (void)flags;
+ atp.user_atfork = atfork;
+ atp.user_atforkvalue = atforkvalue;
if (!ctx || !name || !argv || !argv[0])
return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
- fix_signals ();
+ if (! ctx->flags.no_fixsignals)
+ fix_signals ();
- sprintf (mypidstr, "%lu", (unsigned long)getpid ());
-
- if (pipe (rp) < 0)
- return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
+ if (_assuan_pipe (ctx, rp, 1) < 0)
+ return _assuan_error (ctx, gpg_err_code_from_syserror ());
- if (pipe (wp) < 0)
+ if (_assuan_pipe (ctx, wp, 0) < 0)
{
- close (rp[0]);
- close (rp[1]);
- return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
+ _assuan_close (ctx, rp[0]);
+ _assuan_close (ctx, rp[1]);
+ return _assuan_error (ctx, gpg_err_code_from_syserror ());
}
- /* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID
- stored here is actually soon useless. */
- pid = fork ();
- if (pid < 0)
+ /* FIXME: Use atfork handler that closes child fds on Unix. */
+ res = _assuan_spawn (ctx, &pid, name, argv, wp[0], rp[1],
+ fd_child_list, at_pipe_fork_cb, &atp, flags);
+ if (res < 0)
{
- close (rp[0]);
- close (rp[1]);
- close (wp[0]);
- close (wp[1]);
- return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
+ rc = gpg_err_code_from_syserror ();
+ _assuan_close (ctx, rp[0]);
+ _assuan_close (ctx, rp[1]);
+ _assuan_close (ctx, wp[0]);
+ _assuan_close (ctx, wp[1]);
+ return _assuan_error (ctx, rc);
}
- if (pid == 0)
- {
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- pid_t pid2;
+ /* Close the stdin/stdout child fds in the parent. */
+ _assuan_close (ctx, rp[1]);
+ _assuan_close (ctx, wp[0]);
- if ((pid2 = fork ()) == 0)
-#endif
- {
- int i, n;
- char errbuf[512];
- int *fdp;
-
- if (atfork)
- atfork (atforkvalue, 0);
-
- /* Dup handles to stdin/stdout. */
- if (rp[1] != STDOUT_FILENO)
- {
- if (dup2 (rp[1], STDOUT_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx,
- "dup2 failed in child: %s", strerror (errno));
- _exit (4);
- }
- }
- if (wp[0] != STDIN_FILENO)
- {
- if (dup2 (wp[0], STDIN_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx,
- "dup2 failed in child: %s", strerror (errno));
- _exit (4);
- }
- }
-
- /* Dup stderr to /dev/null unless it is in the list of FDs to be
- passed to the child. */
- fdp = fd_child_list;
- if (fdp)
- {
- for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
- ;
- }
- if (!fdp || *fdp == -1)
- {
- int fd = open ("/dev/null", O_WRONLY);
- if (fd == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx,
- "can't open `/dev/null': %s", strerror (errno));
- _exit (4);
- }
- if (dup2 (fd, STDERR_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "pipe_connect_unix", ctx,
- "dup2(dev/null, 2) failed: %s", strerror (errno));
- _exit (4);
- }
- }
-
-
- /* Close all files which will not be duped and are not in the
- fd_child_list. */
- n = sysconf (_SC_OPEN_MAX);
- if (n < 0)
- n = MAX_OPEN_FDS;
- for (i=0; i < n; i++)
- {
- if ( i == STDIN_FILENO || i == STDOUT_FILENO
- || i == STDERR_FILENO)
- continue;
- fdp = fd_child_list;
- if (fdp)
- {
- while (*fdp != -1 && *fdp != i)
- fdp++;
- }
-
- if (!(fdp && *fdp != -1))
- close(i);
- }
- errno = 0;
-
- /* We store our parents pid in the environment so that the
- execed assuan server is able to read the actual pid of the
- client. The server can't use getppid because it might have
- been double forked before the assuan server has been
- initialized. */
- setenv ("_assuan_pipe_connect_pid", mypidstr, 1);
-
- /* Make sure that we never pass a connection fd variable
- when using a simple pipe. */
- unsetenv ("_assuan_connection_fd");
-
- execv (name, (char *const *) argv);
- /* oops - use the pipe to tell the parent about it */
- snprintf (errbuf, sizeof(errbuf)-1,
- "ERR %d can't exec `%s': %.50s\n",
- _assuan_error (ctx, GPG_ERR_ASS_SERVER_START),
- name, strerror (errno));
- errbuf[sizeof(errbuf)-1] = 0;
- writen (1, errbuf, strlen (errbuf));
- _exit (4);
- }
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- if (pid2 == -1)
- _exit (1);
- else
- _exit (0);
-#endif
- }
-
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- _assuan_waitpid (pid, NULL, 0);
- pid = -1;
-#endif
-
- close (rp[1]);
- close (wp[0]);
-
- ctx->io = &io;
+ ctx->engine.release = _assuan_disconnect;
+ ctx->engine.readfnc = _assuan_simple_read;
+ ctx->engine.writefnc = _assuan_simple_write;
+ ctx->engine.sendfd = NULL;
+ ctx->engine.receivefd = NULL;
ctx->pipe_mode = 1;
ctx->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */
ctx->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */
@@ -350,177 +237,134 @@
_assuan_reset (ctx);
return rc;
}
-#endif /*!HAVE_W32_SYSTEM*/
+/* FIXME: For socketpair_connect, use spawn function and add atfork
+ handler to do the right thing. Instead of stdin and stdout, we
+ extend the fd_child_list by fds[1]. */
+
#ifndef HAVE_W32_SYSTEM
+struct at_socketpair_fork
+{
+ assuan_fd_t peer_fd;
+ void (*user_atfork) (void *opaque, int reserved);
+ void *user_atforkvalue;
+};
+
+
+static void
+at_socketpair_fork_cb (void *opaque, int reserved)
+{
+ struct at_socketpair_fork *atp = opaque;
+
+ if (atp->user_atfork)
+ atp->user_atfork (atp->user_atforkvalue, reserved);
+
+#ifndef HAVE_W32_SYSTEM
+ {
+ char mypidstr[50];
+
+ /* We store our parents pid in the environment so that the execed
+ assuan server is able to read the actual pid of the client.
+ The server can't use getppid because it might have been double
+ forked before the assuan server has been initialized. */
+ sprintf (mypidstr, "%lu", (unsigned long) getpid ());
+ setenv ("_assuan_pipe_connect_pid", mypidstr, 1);
+
+ /* Now set the environment variable used to convey the
+ connection's file descriptor. */
+ sprintf (mypidstr, "%d", atp->peer_fd);
+ if (setenv ("_assuan_connection_fd", mypidstr, 1))
+ _exit (4);
+ }
+#endif
+}
+
+
/* This function is similar to pipe_connect but uses a socketpair and
sets the I/O up to use sendmsg/recvmsg. */
static gpg_error_t
socketpair_connect (assuan_context_t ctx,
- const char *name, const char *argv[],
+ const char *name, const char **argv,
int *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
{
gpg_error_t err;
+ int idx;
int fds[2];
char mypidstr[50];
pid_t pid;
+ int *child_fds = NULL;
+ int child_fds_cnt = 0;
+ struct at_socketpair_fork atp;
+ int rc;
+ TRACE_BEG3 (ctx, ASSUAN_LOG_CTX, "socketpair_connect", ctx,
+ "name=%s,atfork=%p,atforkvalue=%p", name ? name : "(null)",
+ atfork, atforkvalue);
+
+ atp.user_atfork = atfork;
+ atp.user_atforkvalue = atforkvalue;
+
if (!ctx
|| (name && (!argv || !argv[0]))
|| (!name && !argv))
return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
- fix_signals ();
+ if (! ctx->flags.no_fixsignals)
+ fix_signals ();
sprintf (mypidstr, "%lu", (unsigned long)getpid ());
- if ( socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) )
+ while (fd_child_list[child_fds_cnt] != ASSUAN_INVALID_FD)
+ child_fds_cnt++;
+ child_fds = _assuan_malloc (ctx, (child_fds_cnt + 2) * sizeof (int));
+ if (! child_fds)
+ return TRACE_ERR (gpg_err_code_from_syserror ());
+ memcpy (&child_fds[1], fd_child_list, (child_fds_cnt + 1) * sizeof (int));
+
+ if (_assuan_socketpair (ctx, AF_LOCAL, SOCK_STREAM, 0, fds))
{
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx,
- "socketpair failed: %s", strerror (errno));
- return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
+ TRACE_LOG1 ("socketpair failed: %s", strerror (errno));
+ _assuan_free (ctx, child_fds);
+ return TRACE_ERR (GPG_ERR_ASS_GENERAL);
}
+ atp.peer_fd = fds[1];
+ child_fds[0] = fds[1];
- pid = fork ();
- if (pid < 0)
+
+ rc = _assuan_spawn (ctx, &pid, name, argv, ASSUAN_INVALID_FD,
+ ASSUAN_INVALID_FD, child_fds, at_socketpair_fork_cb,
+ &atp, 0);
+ if (rc < 0)
{
- close (fds[0]);
- close (fds[1]);
- /* FIXME: cleanup ctx */
- return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
+ err = gpg_err_code_from_syserror ();
+ _assuan_close (ctx, fds[0]);
+ _assuan_close (ctx, fds[1]);
+ _assuan_free (ctx, child_fds);
+ return TRACE_ERR (err);
}
- if (pid == 0)
- {
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- pid_t pid2;
+ /* For W32, the user needs to know the server-local names of the
+ inherited handles. Return them here. Note that the translation
+ of the peer socketpair fd (fd_child_list[0]) must be done by the
+ wrapper program based on the environment variable
+ _assuan_connection_fd. */
+ for (idx = 0; fd_child_list[idx] != -1; idx++)
+ /* We add 1 to skip over the socketpair end. */
+ fd_child_list[idx] = child_fds[idx + 1];
- if ((pid2 = fork ()) == 0)
-#endif
- {
- int fd, i, n;
- char errbuf[512];
- int *fdp;
-
- if (atfork)
- atfork (atforkvalue, 0);
-
- /* Connect stdin and stdout to /dev/null. */
- fd = open ("/dev/null", O_RDONLY);
- if (fd == -1 || dup2 (fd, STDIN_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx,
- "dup2(dev/null) failed: %s", strerror (errno));
- _exit (4);
- }
- fd = open ("/dev/null", O_WRONLY);
- if (fd == -1 || dup2 (fd, STDOUT_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx,
- "dup2(dev/null) failed: %s", strerror (errno));
- _exit (4);
- }
-
- /* Dup stderr to /dev/null unless it is in the list of FDs to be
- passed to the child. */
- fdp = fd_child_list;
- if (fdp)
- {
- for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
- ;
- }
- if (!fdp || *fdp == -1)
- {
- fd = open ("/dev/null", O_WRONLY);
- if (fd == -1 || dup2 (fd, STDERR_FILENO) == -1)
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx,
- "dup2(dev/null) failed: %s", strerror (errno));
- _exit (4);
- }
- }
-
-
- /* Close all files which will not be duped, are not in the
- fd_child_list and are not the connection fd. */
- n = sysconf (_SC_OPEN_MAX);
- if (n < 0)
- n = MAX_OPEN_FDS;
- for (i=0; i < n; i++)
- {
- if ( i == STDIN_FILENO || i == STDOUT_FILENO
- || i == STDERR_FILENO || i == fds[1])
- continue;
- fdp = fd_child_list;
- if (fdp)
- {
- while (*fdp != -1 && *fdp != i)
- fdp++;
- }
-
- if (!(fdp && *fdp != -1))
- close(i);
- }
- errno = 0;
-
- /* We store our parents pid in the environment so that the
- execed assuan server is able to read the actual pid of the
- client. The server can't use getppid becuase it might have
- been double forked before the assuan server has been
- initialized. */
- setenv ("_assuan_pipe_connect_pid", mypidstr, 1);
-
- /* Now set the environment variable used to convey the
- connection's file descriptor. */
- sprintf (mypidstr, "%d", fds[1]);
- if (setenv ("_assuan_connection_fd", mypidstr, 1))
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "socketpair_connect", ctx,
- "setenv failed: %s", strerror (errno));
- _exit (4);
- }
-
- if (!name)
- {
- /* No name and no args given, thus we don't do an exec
- but continue the forked process. */
- *argv = "server";
-
- /* FIXME: Cleanup. */
- return 0;
- }
-
- execv (name, (char *const *) argv);
- /* oops - use the pipe to tell the parent about it */
- snprintf (errbuf, sizeof(errbuf)-1,
- "ERR %d can't exec `%s': %.50s\n",
- _assuan_error (ctx, GPG_ERR_ASS_SERVER_START),
- name, strerror (errno));
- errbuf[sizeof(errbuf)-1] = 0;
- writen (fds[1], errbuf, strlen (errbuf));
- _exit (4);
- }
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- if (pid2 == -1)
- _exit (1);
- else
- _exit (0);
-#endif
+ /* If this is the server child process, exit early. */
+ if (! name && (*argv)[0] == 's')
+ {
+ _assuan_free (ctx, child_fds);
+ _assuan_close (ctx, fds[0]);
+ return 0;
}
- if (! name)
- *argv = "client";
+ _assuan_close (ctx, fds[1]);
-#ifdef _ASSUAN_USE_DOUBLE_FORK
- _assuan_waitpid (pid, NULL, 0);
- pid = -1;
-#endif
-
- close (fds[1]);
-
ctx->pipe_mode = 1;
ctx->inbound.fd = fds[0];
ctx->outbound.fd = fds[0];
@@ -535,282 +379,6 @@
}
#endif /*!HAVE_W32_SYSTEM*/
-
-
-#ifdef HAVE_W32_SYSTEM
-/* Build a command line for use with W32's CreateProcess. On success
- CMDLINE gets the address of a newly allocated string. */
-static int
-build_w32_commandline (assuan_context_t ctx, const char * const *argv, char **cmdline)
-{
- int i, n;
- const char *s;
- char *buf, *p;
-
- *cmdline = NULL;
- n = 0;
- for (i=0; (s=argv[i]); i++)
- {
- n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
- for (; *s; s++)
- if (*s == '\"')
- n++; /* Need to double inner quotes. */
- }
- n++;
-
- buf = p = _assuan_malloc (ctx, n);
- if (!buf)
- return -1;
-
- for (i=0; argv[i]; i++)
- {
- if (i)
- p = stpcpy (p, " ");
- if (!*argv[i]) /* Empty string. */
- p = stpcpy (p, "\"\"");
- else if (strpbrk (argv[i], " \t\n\v\f\""))
- {
- p = stpcpy (p, "\"");
- for (s=argv[i]; *s; s++)
- {
- *p++ = *s;
- if (*s == '\"')
- *p++ = *s;
- }
- *p++ = '\"';
- *p = 0;
- }
- else
- p = stpcpy (p, argv[i]);
- }
-
- *cmdline= buf;
- return 0;
-}
-#endif /*HAVE_W32_SYSTEM*/
-
-
-#ifdef HAVE_W32_SYSTEM
-/* Create pipe where one end end is inheritable. */
-static int
-create_inheritable_pipe (assuan_context_t ctx,
- assuan_fd_t filedes[2], int for_write)
-{
- HANDLE r, w, h;
- SECURITY_ATTRIBUTES sec_attr;
-
- memset (&sec_attr, 0, sizeof sec_attr );
- sec_attr.nLength = sizeof sec_attr;
- sec_attr.bInheritHandle = FALSE;
-
- if (!CreatePipe (&r, &w, &sec_attr, 0))
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx,
- "CreatePipe failed: %s", _assuan_w32_strerror (ctx, -1));
- return -1;
- }
-
- if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w,
- GetCurrentProcess(), &h, 0,
- TRUE, DUPLICATE_SAME_ACCESS ))
- {
- TRACE1 (ctx, ASSUAN_LOG_SYSIO, "create_inheritable_pipe", ctx,
- "DuplicateHandle failed: %s", _assuan_w32_strerror (ctx, -1));
- CloseHandle (r);
- CloseHandle (w);
- return -1;
- }
- if (for_write)
- {
- CloseHandle (r);
- r = h;
- }
- else
- {
- CloseHandle (w);
- w = h;
- }
-
- filedes[0] = r;
- filedes[1] = w;
- return 0;
-}
-#endif /*HAVE_W32_SYSTEM*/
-
-
-#ifdef HAVE_W32_SYSTEM
-#define pipe_connect pipe_connect_w32
-/* W32 version of the pipe connection code. */
-static gpg_error_t
-pipe_connect_w32 (assuan_context_t ctx,
- const char *name, const char *const argv[],
- int *fd_child_list,
- void (*atfork) (void *opaque, int reserved),
- void *atforkvalue, unsigned int flags)
-{
- gpg_error_t err;
- assuan_fd_t rp[2];
- assuan_fd_t wp[2];
- char mypidstr[50];
- char *cmdline;
- SECURITY_ATTRIBUTES sec_attr;
- PROCESS_INFORMATION pi =
- {
- NULL, /* Returns process handle. */
- 0, /* Returns primary thread handle. */
- 0, /* Returns pid. */
- 0 /* Returns tid. */
- };
- STARTUPINFO si;
- int fd, *fdp;
- HANDLE nullfd = INVALID_HANDLE_VALUE;
- static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
- 0, 0 };
-
- if (!ctx || !name || !argv || !argv[0])
- return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
-
- fix_signals ();
-
- sprintf (mypidstr, "%lu", (unsigned long)getpid ());
-
- /* Build the command line. */
- if (build_w32_commandline (ctx, argv, &cmdline))
- return _assuan_error (ctx, gpg_err_code_from_syserror ());
-
- /* Create thew two pipes. */
- if (create_inheritable_pipe (ctx, rp, 0))
More information about the Gnupg-commits
mailing list