diff --git a/TODO b/TODO index 56b58ac5..2c180e03 100644 --- 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 diff --git a/doc/ChangeLog b/doc/ChangeLog index 38e53a68..04ce809d 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2008-03-11 Marcus Brinkmann + + * gpgme.texi (File Based Data Buffers): Document the need for + blocking operations. + (Callback Based Data Buffers): Likewise. + 2008-03-05 Marcus Brinkmann * gpgme.texi (Library Version Check): Rename snippet function to diff --git a/doc/gpgme.texi b/doc/gpgme.texi index d854f98c..1f1a8a6c 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -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. diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index a27204c6..35af33ad 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,7 @@ +2008-03-11 Marcus Brinkmann + + * data.c (gpgme_data_read, gpgme_data_write): Retry on EINTR. + 2008-03-06 Marcus Brinkmann * key.c (_gpgme_key_add_sig): Terminate UID in case SRC is NULL. diff --git a/gpgme/data.c b/gpgme/data.c index aa3eeb38..18d9c71b 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -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); }