diff options
author | Werner Koch <[email protected]> | 2006-09-12 11:07:18 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2006-09-12 11:07:18 +0000 |
commit | d1210ab25c96e60fc439cfa9b50ec431642ada36 (patch) | |
tree | c123ce388013b3d83914648caf00b44e1d8d356d /src/assuan-io.c | |
parent | Added stuff to the manual. Minor prototype cleanups. (diff) | |
download | libassuan-d1210ab25c96e60fc439cfa9b50ec431642ada36.tar.gz libassuan-d1210ab25c96e60fc439cfa9b50ec431642ada36.zip |
Integrated descriptor passing.
Diffstat (limited to 'src/assuan-io.c')
-rw-r--r-- | src/assuan-io.c | 134 |
1 files changed, 132 insertions, 2 deletions
diff --git a/src/assuan-io.c b/src/assuan-io.c index 30302d6..3a3a017 100644 --- a/src/assuan-io.c +++ b/src/assuan-io.c @@ -1,5 +1,5 @@ /* assuan-io.c - Wraps the read and write functions. - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. * * This file is part of Assuan. * @@ -23,23 +23,69 @@ #include <config.h> #endif -#include "assuan-defs.h" #include <sys/types.h> +#include <sys/socket.h> +#if HAVE_SYS_UIO_H +#include <sys/uio.h> +#endif #include <unistd.h> +#include <errno.h> #ifdef HAVE_W32_SYSTEM #include <windows.h> #endif +#include "assuan-defs.h" + +/* We can't include pth.h and we are not sure whether other headers + already included it. This we define macros with the same + values. */ +#define MY_PTH_FDMODE_ERROR (-1) +#define MY_PTH_FDMODE_POLL 0 +#define MY_PTH_FDMODE_BLOCK 1 +#define MY_PTH_FDMODE_NONBLOCK 2 + + #ifndef _ASSUAN_NO_PTH extern ssize_t pth_read (int fd, void *buffer, size_t size); extern ssize_t pth_write (int fd, const void *buffer, size_t size); +extern int pth_fdmode (int, int); +extern int pth_select(int, fd_set*, fd_set*, fd_set*, struct timeval*); #ifndef HAVE_W32_SYSTEM #pragma weak pth_read #pragma weak pth_write +#pragma weak pth_fdmode +#pragma weak pth_select #endif #endif /*!_ASSUAN_NO_PTH*/ +#ifndef _ASSUAN_NO_PTH +/* Wrapper around pth_fdmode. */ +static int +my_pth_fdmode (int fd, int mode) +{ + if (pth_fdmode) + return pth_fdmode (fd, mode); + else + return MY_PTH_FDMODE_NONBLOCK; /* This is okay, given the way we use it. */ +} +#endif /*_ASSUAN_NO_PTH*/ + +#ifndef _ASSUAN_NO_PTH +/* Wrapper around pth_select. */ +static int +my_pth_select (int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, + struct timeval *timeout) +{ + if (pth_select) + return pth_select (nfd, rfds, wfds, efds, timeout); + else + return 1; /* Fake one fd ready; this is okay, given the way we use it. */ +} +#endif /*_ASSUAN_NO_PTH*/ + + + ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { @@ -69,3 +115,87 @@ _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) # endif #endif } + + +ssize_t +_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#if defined(HAVE_W32_SYSTEM) + return _assuan_error (ASSUAN_Not_Implemented); +#elif defined(_ASSUAN_NO_PTH) + int ret; + while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#else + /* Pth does not provide a sendmsg function. Thus we implement it here. */ + int ret; + int fd = ctx->outbound.fd; + int fdmode; + + fdmode = my_pth_fdmode (fd, MY_PTH_FDMODE_POLL); + if (fdmode == MY_PTH_FDMODE_ERROR) + { + errno = EBADF; + return -1; + } + if (fdmode == MY_PTH_FDMODE_BLOCK) + { + fd_set fds; + + FD_ZERO (&fds); + FD_SET (fd, &fds); + while ( (ret = my_pth_select (fd+1, NULL, &fds, NULL, NULL)) < 0 + && errno == EINTR) + ; + if (ret < 0) + return -1; + } + + while ((ret = sendmsg (fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} + + +ssize_t +_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#if defined(HAVE_W32_SYSTEM) + return _assuan_error (ASSUAN_Not_Implemented); +#elif defined(_ASSUAN_NO_PTH) + int ret; + while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#else + /* Pth does not provide a recvmsg function. Thus we implement it here. */ + int ret; + int fd = ctx->inbound.fd; + int fdmode; + + fdmode = my_pth_fdmode (fd, MY_PTH_FDMODE_POLL); + if (fdmode == MY_PTH_FDMODE_ERROR) + { + errno = EBADF; + return -1; + } + if (fdmode == MY_PTH_FDMODE_BLOCK) + { + fd_set fds; + + FD_ZERO (&fds); + FD_SET (fd, &fds); + while ( (ret = my_pth_select (fd+1, &fds, NULL, NULL, NULL)) < 0 + && errno == EINTR) + ; + if (ret < 0) + return -1; + } + + while ((ret = recvmsg (fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} |