doc/
authorMarcus Brinkmann <mb@g10code.com>
Tue, 11 Mar 2008 16:05:40 +0000 (16:05 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Tue, 11 Mar 2008 16:05:40 +0000 (16:05 +0000)
2008-03-11  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (File Based Data Buffers): Document the need for
blocking operations.
(Callback Based Data Buffers): Likewise.

gpgme/
2008-03-11  Marcus Brinkmann  <marcus@g10code.de>

* data.c (gpgme_data_read, gpgme_data_write): Retry on EINTR.

TODO
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/data.c

diff --git a/TODO b/TODO
index 56b58ac57ca6e9b1225131550dbd3db00450a986..2c180e035295055ef1ff11d1ccbfd4c9cc63dcd4 100644 (file)
--- a/TODO
+++ b/TODO
@@ -41,6 +41,15 @@ Hey Emacs, this is -*- outline -*- mode!
    There is a configure time warning, though.
 
 * New features:
+** Flow control for data objects.
+   Currently, gpgme_data_t objects are assumed to be blocking.  To
+   break this assumption, we need either (A) a way for an user I/O
+   callback to store the current operation in a continuation that can
+   be resumed later.  While the continuation exists, file descriptors
+   associated with this operation must be removed from their
+   respective event loop.  or (B) a way for gpgme data objects to be
+   associated with a waitable object, that can be registered with the
+   user event loop.  Neither is particularly simple.
 ** Extended notation support.  When gpg supports arbitrary binary
    notation data, provide a user interface for that.
 ** notification system
index 38e53a688a8cb88fa80133de3a8c5ff0b1b4cc0b..04ce809d115aa6a002d292c4dc622d6b15847b02 100644 (file)
@@ -1,3 +1,9 @@
+2008-03-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (File Based Data Buffers): Document the need for
+       blocking operations.
+       (Callback Based Data Buffers): Likewise.
+
 2008-03-05  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.texi (Library Version Check): Rename snippet function to
index d854f98cc891c1eb9350ad1689c8073de8de472f..1f1a8a6cb4cdd5990cf3c4378993c6ec9a85e80c 100644 (file)
@@ -1464,6 +1464,14 @@ The @code{gpgme_data_t} type is a handle for a container for generic
 data, which is used by @acronym{GPGME} to exchange data with the user.
 @end deftp
 
+@code{gpgme_data_t} objects do not provide notifications on events.
+It is assumed that read and write operations are blocking until data
+is available.  If this is undesirable, the application must ensure
+that all GPGME data operations always have data available, for example
+by using memory buffers or files rather than pipes or sockets.  This
+might be relevant, for example, if the external event loop mechanism
+is used.
+
 @menu
 * Creating Data Buffers::         Creating new data buffers.
 * Destroying Data Buffers::       Releasing data buffers.
@@ -1575,6 +1583,10 @@ When using the data object as an input buffer, the function might read
 a bit more from the file descriptor than is actually needed by the
 crypto engine in the desired operation because of internal buffering.
 
+Note that GPGME assumes that the file descriptor is set to blocking
+mode.  Errors during I/O operations, except for EINTR, are usually
+fatal for crypto operations.
+
 The function returns the error code @code{GPG_ERR_NO_ERROR} if the
 data object was successfully created, and @code{GPG_ERR_ENOMEM} if not
 enough memory is available.
@@ -1590,6 +1602,10 @@ When using the data object as an input buffer, the function might read
 a bit more from the stream than is actually needed by the crypto
 engine in the desired operation because of internal buffering.
 
+Note that GPGME assumes that the stream is in blocking mode.  Errors
+during I/O operations, except for EINTR, are usually fatal for crypto
+operations.
+
 The function returns the error code @code{GPG_ERR_NO_ERROR} if the
 data object was successfully created, and @code{GPG_ERR_ENOMEM} if not
 enough memory is available.
@@ -1611,6 +1627,10 @@ data object.  The function should read up to @var{size} bytes from the
 current read position into the space starting at @var{buffer}.  The
 @var{handle} is provided by the user at data object creation time.
 
+Note that GPGME assumes that the read blocks until data is available.
+Errors during I/O operations, except for EINTR, are usually fatal for
+crypto operations.
+
 The function should return the number of bytes read, 0 on EOF, and -1
 on error.  If an error occurs, @var{errno} should be set to describe
 the type of the error.
@@ -1624,6 +1644,10 @@ data object.  The function should write up to @var{size} bytes to the
 current write position from the space starting at @var{buffer}.  The
 @var{handle} is provided by the user at data object creation time.
 
+Note that GPGME assumes that the write blocks until data is available.
+Errors during I/O operations, except for EINTR, are usually fatal for
+crypto operations.
+
 The function should return the number of bytes written, and -1 on
 error.  If an error occurs, @var{errno} should be set to describe the
 type of the error.
index a27204c6f3b2cb90296be9bfe7088ec9267db3a5..35af33adedb5c64c7472fb91928f1a308cfdcf45 100644 (file)
@@ -1,3 +1,7 @@
+2008-03-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * data.c (gpgme_data_read, gpgme_data_write): Retry on EINTR.
+
 2008-03-06  Marcus Brinkmann  <marcus@g10code.de>
 
        * key.c (_gpgme_key_add_sig): Terminate UID in case SRC is NULL.
index aa3eeb386393e16d4d784b40434b8a454eb55bbb..18d9c71b223977b69a3e18f678526d07e548bcb1 100644 (file)
@@ -87,7 +87,10 @@ gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
       errno = ENOSYS;
       return TRACE_SYSRES (-1);
     }
-  res = (*dh->cbs->read) (dh, buffer, size);
+  do
+    res = (*dh->cbs->read) (dh, buffer, size);
+  while (res < 0 && errno == EINTR);
+
   return TRACE_SYSRES (res);
 }
 
@@ -112,7 +115,10 @@ gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
       errno = ENOSYS;
       return TRACE_SYSRES (-1);
     }
-  res = (*dh->cbs->write) (dh, buffer, size);
+  do
+    res = (*dh->cbs->write) (dh, buffer, size);
+  while (res < 0 && errno == EINTR);
+
   return TRACE_SYSRES (res);
 }