The W32 version does not compile at the meoment.
* Allow to use GTK's main loop instead of the select stuff in
wait.c
-* a op_keylist_start should cancel a pending keylisy operation on the
- same context
-
* need to close a lot of handles in w32-io.c
+2001-02-19 Werner Koch <wk@gnupg.org>
+
+ * posix-io.c (_gpgme_io_select): Use a 1 sec timeout and not 200
+ microseconds.
+
+ * wait.c (remove_process): Don't close the fd here.
+ (do_select): Set the fd to -1 and remove the is_closed flag everywhere.
+ (_gpgme_wait_on_condition): Remove the assert on the queue and
+ break out if we could not find the queue. The whole thing should
+ be reworked.
+
+ * posix-io.c (_gpgme_io_set_close_notify): New.
+ (_gpgme_io_close): Do the notification.
+
+ * rungpg.c (close_notify_handler): New.
+ (_gpgme_gpg_new): Register a callback for the fd.
+ (_gpgme_gpg_set_colon_line_handler): Ditto.
+ (build_argv): Ditto
+
2001-02-13 Werner Koch <wk@gnupg.org>
* rungpg.c (struct reap_s): Replaced pid_t by int.
int _gpgme_io_write ( int fd, const void *buffer, size_t count );
int _gpgme_io_pipe ( int filedes[2], int inherit_idx );
int _gpgme_io_close ( int fd );
+int _gpgme_io_set_close_notify (int fd,
+ void (*handler)(int, void*), void *value);
int _gpgme_io_set_nonblocking ( int fd );
int _gpgme_io_spawn ( const char *path, char **argv,
struct spawn_fd_item_s *fd_child_list,
#include "util.h"
#include "io.h"
+static struct {
+ void (*handler)(int,void*);
+ void *value;
+} notify_table[256];
+
+
int
_gpgme_io_read ( int fd, void *buffer, size_t count )
{
{
if ( fd == -1 )
return -1;
+ /* first call the notify handler */
+ DEBUG1 ("closing fd %d", fd );
+ if ( fd >= 0 && fd < DIM (notify_table) ) {
+ if (notify_table[fd].handler) {
+ notify_table[fd].handler (fd, notify_table[fd].value);
+ notify_table[fd].handler = NULL;
+ notify_table[fd].value = NULL;
+ }
+ }
+ /* then do the close */
return close (fd);
}
+int
+_gpgme_io_set_close_notify (int fd, void (*handler)(int, void*), void *value)
+{
+ assert (fd != -1);
+
+ if ( fd < 0 || fd >= DIM (notify_table) )
+ return -1;
+ DEBUG1 ("set notification for fd %d", fd );
+ notify_table[fd].handler = handler;
+ notify_table[fd].value = value;
+ return 0;
+}
+
+
int
_gpgme_io_set_nonblocking ( int fd )
{
static fd_set readfds;
static fd_set writefds;
int any, i, max_fd, n, count;
- struct timeval timeout = { 0, 200 }; /* Use a 200ms timeout */
+ struct timeval timeout = { 1, 0 }; /* Use a 1s timeout */
void *dbg_help;
FD_ZERO ( &readfds );
char *buffer, size_t length, size_t *nread );
+static void
+close_notify_handler ( int fd, void *opaque )
+{
+ GpgObject gpg = opaque;
+
+ assert (fd != -1);
+ if (gpg->status.fd[0] == fd )
+ gpg->status.fd[0] = -1;
+ else if (gpg->status.fd[1] == fd )
+ gpg->status.fd[1] = -1;
+ else if (gpg->colon.fd[0] == fd )
+ gpg->colon.fd[0] = -1;
+ else if (gpg->colon.fd[1] == fd )
+ gpg->colon.fd[1] = -1;
+ else if (gpg->fd_data_map) {
+ int i;
+
+ for (i=0; gpg->fd_data_map[i].data; i++ ) {
+ if ( gpg->fd_data_map[i].fd == fd ) {
+ gpg->fd_data_map[i].fd = -1;
+ break;
+ }
+ if ( gpg->fd_data_map[i].peer_fd == fd ) {
+ gpg->fd_data_map[i].peer_fd = -1;
+ break;
+ }
+ }
+ }
+}
+
+
+
GpgmeError
_gpgme_gpg_new ( GpgObject *r_gpg )
rc = mk_error (Pipe_Error);
goto leave;
}
+ if ( _gpgme_io_set_close_notify (gpg->status.fd[0],
+ close_notify_handler, gpg)
+ || _gpgme_io_set_close_notify (gpg->status.fd[1],
+ close_notify_handler, gpg) ) {
+ rc = mk_error (General_Error);
+ goto leave;
+ }
gpg->status.eof = 0;
_gpgme_gpg_add_arg ( gpg, "--status-fd" );
{
free_argv (gpg->argv);
xfree (gpg->cmd.keyword);
- #if 0
- /* fixme: We need a way to communicate back closed fds, so that we
- * don't do it a second time. One way to do it is by using a global
- * table of open fds associated with gpg objects - but this requires
- * additional locking. */
if (gpg->status.fd[0] != -1 )
_gpgme_io_close (gpg->status.fd[0]);
if (gpg->status.fd[1] != -1 )
_gpgme_io_close (gpg->colon.fd[0]);
if (gpg->colon.fd[1] != -1 )
_gpgme_io_close (gpg->colon.fd[1]);
- #endif
free_fd_data_map (gpg->fd_data_map);
if (gpg->running) {
int pid = gpg->pid;
xfree (gpg);
}
+
static void
do_reaping (void)
{
xfree (gpg->colon.buffer); gpg->colon.buffer = NULL;
return mk_error (Pipe_Error);
}
+ if ( _gpgme_io_set_close_notify (gpg->colon.fd[0],
+ close_notify_handler, gpg)
+ || _gpgme_io_set_close_notify (gpg->colon.fd[1],
+ close_notify_handler, gpg) ) {
+ return mk_error (General_Error);
+ }
gpg->colon.eof = 0;
gpg->colon.fnc = fnc;
gpg->colon.fnc_value = fnc_value;
return;
for (i=0; fd_data_map[i].data; i++ ) {
-#if 0 /* fixme -> see gpg_release */
if ( fd_data_map[i].fd != -1 )
_gpgme_io_close (fd_data_map[i].fd);
if ( fd_data_map[i].peer_fd != -1 )
_gpgme_io_close (fd_data_map[i].peer_fd);
-#endif
/* don't release data because this is only a reference */
}
xfree (fd_data_map);
free_argv (argv);
return mk_error (Pipe_Error);
}
+ if ( _gpgme_io_set_close_notify (fds[0],
+ close_notify_handler, gpg)
+ || _gpgme_io_set_close_notify (fds[1],
+ close_notify_handler,
+ gpg)) {
+ return mk_error (General_Error);
+ }
/* if the data_type is FD, we have to do a dup2 here */
if (fd_data_map[datac].inbound) {
fd_data_map[datac].fd = fds[0];
*
* Return a key object which was used to check the signature.
*
- * Return value: An Errorcode or 0 for success. GPG<ME_EOF is returned to
+ * Return value: An Errorcode or 0 for success. GPGME_EOF is returned to
* indicate that there are no more signatures.
**/
GpgmeError
}
/* remove the given process from the queue */
+/* FIXME: We should do this on demand from rungpg.c */
static void
remove_process ( int pid )
{
if (fd_table[i].fd != -1 && (q=fd_table[i].opaque) && q->pid == pid ) {
xfree (q);
fd_table[i].opaque = NULL;
-
- if ( !fd_table[i].is_closed ) {
- _gpgme_io_close (fd_table[i].fd);
- fd_table[i].is_closed = 1;
- }
fd_table[i].fd = -1;
}
}
* alive */
assert (c); /* !c is not yet implemented */
q = queue_item_from_context ( c );
- assert (q);
-
- if ( !count_active_and_thawed_fds (q->pid) ) {
- remove_process (q->pid);
- hang = 0;
+ if (q) {
+ if ( !count_active_and_thawed_fds (q->pid) ) {
+ remove_process (q->pid);
+ hang = 0;
+ }
}
+ else
+ hang = 0;
}
if (hang)
run_idle ();
q->active = 0;
fd_table[i].for_read = 0;
fd_table[i].for_write = 0;
- fd_table[i].is_closed = 1;
+ fd_table[i].fd = -1;
}
}
}
for (i=0; i < fd_table_size; i++ ) {
if ( fd_table[i].fd == -1 ) {
fd_table[i].fd = fd;
- fd_table[i].is_closed = 0;
fd_table[i].for_read = inbound;
fd_table[i].for_write = !inbound;
fd_table[i].signaled = 0;
puts ("checking a valid message:\n");
err = gpgme_op_verify (ctx, sig, text, &status );
print_sig_stat ( ctx, status );
+ print_sig_stat ( ctx, status );
+ print_sig_stat ( ctx, status );
+ print_sig_stat ( ctx, status );
fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) )