FD are now released and a major bug has been fixed.
authorWerner Koch <wk@gnupg.org>
Mon, 19 Feb 2001 17:22:38 +0000 (17:22 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 19 Feb 2001 17:22:38 +0000 (17:22 +0000)
The W32 version does not compile at the meoment.

TODO
gpgme/ChangeLog
gpgme/io.h
gpgme/posix-io.c
gpgme/rungpg.c
gpgme/verify.c
gpgme/wait.c
tests/t-verify.c

diff --git a/TODO b/TODO
index 1ef478d..c6f6505 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,7 +5,4 @@
 * 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
index bcb7135..0c8722e 100644 (file)
@@ -1,3 +1,22 @@
+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.
index efe2c78..2f9f1b7 100644 (file)
@@ -46,6 +46,8 @@ int _gpgme_io_read ( int fd, void *buffer, size_t count );
 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,
index 2e7e2c9..3cd2bd5 100644 (file)
 #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 )
 {
@@ -75,10 +81,34 @@ _gpgme_io_close ( int fd )
 {
     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 )
 {
     int flags;
@@ -225,7 +255,7 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
     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 );
index 261c71f..b042d7b 100644 (file)
@@ -145,6 +145,38 @@ static int command_cb ( void *opaque,
                         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 )
@@ -179,6 +211,13 @@ _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" );
     {
@@ -211,11 +250,6 @@ _gpgme_gpg_release ( GpgObject gpg )
         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 )
@@ -224,7 +258,6 @@ _gpgme_gpg_release ( GpgObject gpg )
         _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;
@@ -246,6 +279,7 @@ _gpgme_gpg_release ( GpgObject gpg )
         xfree (gpg);
 }
 
+
 static void
 do_reaping (void)
 {
@@ -438,6 +472,12 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
         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;
@@ -512,12 +552,10 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map )
         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);
@@ -652,6 +690,13 @@ build_argv ( GpgObject gpg )
                     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];
index 7a1af98..ce6a2ba 100644 (file)
@@ -406,7 +406,7 @@ gpgme_get_sig_status (GpgmeCtx c, int idx,
  * 
  * 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
index a7d137c..e2c4636 100644 (file)
@@ -94,6 +94,7 @@ count_active_and_thawed_fds ( int pid )
 }
 
 /* remove the given process from the queue */
+/* FIXME: We should do this on demand from rungpg.c */
 static void
 remove_process ( int pid )
 {
@@ -104,11 +105,6 @@ 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;
         }
     }
@@ -151,12 +147,14 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
              * 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 ();
@@ -201,7 +199,7 @@ do_select ( void )
                 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;
             }
         }
     }
@@ -242,7 +240,6 @@ _gpgme_register_pipe_handler ( void *opaque,
     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;
index 9372a7c..e0fbbe3 100644 (file)
@@ -150,6 +150,9 @@ main (int argc, char **argv )
     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)) )