Fixed W32 bugs and one major bug which swallowed up some output.
authorWerner Koch <wk@gnupg.org>
Wed, 31 Jan 2001 12:39:53 +0000 (12:39 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 31 Jan 2001 12:39:53 +0000 (12:39 +0000)
TODO
gpgme/ChangeLog
gpgme/debug.c
gpgme/rungpg.c
gpgme/version.c
gpgme/w32-io.c
gpgme/wait.c

diff --git a/TODO b/TODO
index a829ea0e796678644aff1a5e27f5c5e3a2753cda..c6f650577fd989e6c19a06050c8e6fef93af48ec 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,6 +5,4 @@
 * Allow to use GTK's main loop instead of the select stuff in
   wait.c
 
-* Remove all that funny exit code handling - we don't need it.
-
-
+* need to close a lot of handles in w32-io.c
index 2b8c2370b470ab17355d31d053150453a520ff6a..458b3c9744a554f24a0a796328e7a76a4c00bae8 100644 (file)
@@ -1,3 +1,13 @@
+2001-01-31  Werner Koch  <wk@gnupg.org>
+
+       * wait.c (_gpgme_wait_on_condition): Remove all exit code processing.
+       (propagate_term_results,clear_active_fds): Removed.
+       (count_active_fds): Renamed to .. 
+       (count_active_and_thawed_fds): .. this and count only thawed fds. 
+
+       * rungpg.c (gpg_colon_line_handler): Return colon.eof and not
+       status.eof ;-)
+
 2001-01-30  Werner Koch  <wk@gnupg.org>
 
        * w32-io.c (_gpgme_io_spawn): Use the supplied path arg.
index 7cb5121d952157946f616c0309e92065501eae89..e700405bfe784aadd7aa13a073ad9bab639ba8f0 100644 (file)
@@ -139,6 +139,7 @@ _gpgme_debug_end (void **helper, const char *text)
         return;
     
     _gpgme_debug_add (helper, "%s", text );
+    fflush (ctl->fp); /* we need this for the buggy Windoze libc */
     rewind (ctl->fp);
     LOCK (debug_lock);
     while ( (c=getc (ctl->fp)) != EOF ) {
@@ -149,6 +150,7 @@ _gpgme_debug_end (void **helper, const char *text)
         putc ('\n', stderr);
     UNLOCK (debug_lock);
     
+    fclose (ctl->fp);
     remove (ctl->fname);
     xfree (ctl);
     *helper = NULL;
index 8c9d2b77c385d77daa80fb4bfe67bb374d19a607..5250b56568f8e4eb4f794d74054e089bf598b6ab 100644 (file)
@@ -1018,7 +1018,8 @@ read_status ( GpgObject gpg )
                         }
                     }
                     if ( r->code == STATUS_END_STREAM ) {
-                        /* _gpgme_freeze_fd ( ? );*/
+                        if ( gpg->cmd.used )
+                            _gpgme_freeze_fd ( gpg->cmd.fd );
                     }
                 }
                 /* To reuse the buffer for the next line we have to
@@ -1066,7 +1067,7 @@ gpg_colon_line_handler ( void *opaque, int pid, int fd )
         return 1;
     }
 
-    return gpg->status.eof;
+    return gpg->colon.eof;
 }
 
 static GpgmeError
index 6013d27d886934a363edefd938d20fa9031eed2d..cac19826f7c46c8793ffb0fb9b83390d6e1e1b68 100644 (file)
@@ -216,14 +216,14 @@ version_line_handler ( GpgmeCtx c, char *line )
 static const char *
 get_engine_info (void)
 {
-    const char *engine_info =NULL;
+    static const char *engine_info =NULL;
     GpgmeCtx c = NULL;
     GpgmeError err = 0;
     const char *path = NULL;
 
     /* FIXME: make sure that only one instance does run */
     if (engine_info)
-        goto leave;
+        return engine_info;
 
     path = _gpgme_get_gpg_path ();
     err = gpgme_new (&c);
@@ -299,3 +299,7 @@ get_engine_info (void)
 }
 
 
+
+
+
+
index 2ee10bbbd48ae88adea98a51c9329d73782e9ef0..82e8f819311a1282e5532cd204bf95f53c39c807 100644 (file)
@@ -58,12 +58,11 @@ struct reader_context_s {
     DECLARE_LOCK (mutex);
     
     int eof;
+    int eof_shortcut;
     int error;
     int error_code;
 
     HANDLE have_data_ev;  /* manually reset */
-    int    have_data_flag;  /* FIXME: is there another way to check whether
-                               it has been signaled? */
     HANDLE have_space_ev; /* auto reset */
     size_t readpos, writepos;
     char buffer[READBUF_SIZE];
@@ -128,10 +127,17 @@ reader (void *arg)
         DEBUG2 ("reader thread %p: reading %d bytes", c->thread_hd, nbytes );
         if ( !ReadFile ( c->file_hd,
                          c->buffer+c->writepos, nbytes, &nread, NULL) ) {
-            c->error = 1;
             c->error_code = (int)GetLastError ();
-            DEBUG2 ("reader thread %p: read error: ec=%d",
-                    c->thread_hd, c->error_code );
+            if (c->error_code == ERROR_BROKEN_PIPE ) {
+                c->eof=1;
+                DEBUG1 ("reader thread %p: got eof (broken pipe)",
+                        c->thread_hd );
+            }
+            else {
+                c->error = 1;
+                DEBUG2 ("reader thread %p: read error: ec=%d",
+                        c->thread_hd, c->error_code );
+            }
             break;
         }
         if ( !nread ) {
@@ -143,10 +149,11 @@ reader (void *arg)
       
         LOCK (c->mutex);
         c->writepos = (c->writepos + nread) % READBUF_SIZE;
-        c->have_data_flag = 1;
         SetEvent (c->have_data_ev);
         UNLOCK (c->mutex);
     }
+    /* indicate that we have an error or eof */
+    SetEvent (c->have_data_ev);
     DEBUG1 ("reader thread %p ended", c->thread_hd );
 
     return 0;
@@ -245,34 +252,45 @@ _gpgme_io_read ( int fd, void *buffer, size_t count )
         DEBUG0 ( "no reader thread\n");
         return -1;
     }
+    if (c->eof_shortcut) {
+        DEBUG1 ("fd %d: EOF (again)", fd );
+        return 0;
+    }
 
     LOCK (c->mutex);
-    if (c->readpos == c->writepos) { /* no data avail */
+    if (c->readpos == c->writepos && !c->error) { /*no data avail*/
         UNLOCK (c->mutex);
         DEBUG2 ("fd %d: waiting for data from thread %p", fd, c->thread_hd);
         WaitForSingleObject (c->have_data_ev, INFINITE);
         DEBUG2 ("fd %d: data from thread %p available", fd, c->thread_hd);
         LOCK (c->mutex);
-        if (c->readpos == c->writepos && !c->eof && !c->error) {
-            UNLOCK (c->mutex);
-            if (c->eof) 
-                return 0;
-            return -1;
-       }
     }
-  
+    
+    if (c->readpos == c->writepos || c->error) {
+        UNLOCK (c->mutex);
+        c->eof_shortcut = 1;
+        if (c->eof) {
+            DEBUG1 ("fd %d: EOF", fd );
+            return 0;
+        }
+        if (!c->error) {
+            DEBUG1 ("fd %d: EOF but eof flag not set", fd );
+            return 0;
+        }
+        DEBUG1 ("fd %d: read error", fd );
+        return -1;
+    }
+      
     nread = c->readpos < c->writepos? c->writepos - c->readpos
                                     : READBUF_SIZE - c->readpos;
     if (nread > count)
         nread = count;
     memcpy (buffer, c->buffer+c->readpos, nread);
     c->readpos = (c->readpos + nread) % READBUF_SIZE;
-    if (c->readpos == c->writepos) {
-        c->have_data_flag = 0;
+    if (c->readpos == c->writepos && !c->eof) {
         ResetEvent (c->have_data_ev);
     }
-    if (nread)
-        SetEvent (c->have_space_ev);
+    SetEvent (c->have_space_ev);
     UNLOCK (c->mutex);
 
     DEBUG2 ("fd %d: got %d bytes\n", fd, nread );
@@ -287,9 +305,9 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
     DWORD nwritten;
     HANDLE h = fd_to_handle (fd);
 
-#warning writing blocks for large counts, so we limit it here.
-    if (count > 500)
-        count = 500;
+    /* writing blocks for large counts, so we limit it here. */
+    if (count > 1024)
+        count = 1024;
 
     DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count );
     if ( !WriteFile ( h, buffer, count, &nwritten, NULL) ) {
@@ -587,6 +605,7 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
 {
 #if 1
     HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
+    int    waitidx[MAXIMUM_WAIT_OBJECTS];
     int code, nwait;
     int i, any, any_write;
     int count;
@@ -599,27 +618,26 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
     for ( i=0; i < nfds; i++ ) {
         if ( fds[i].fd == -1 ) 
             continue;
-        if ( fds[i].for_read ) {
-            if ( nwait >= DIM (waitbuf) ) {
-                DEBUG_END (dbg_help, "oops ]");
-                DEBUG0 ("Too many objects for WFMO!" );
-                return -1;
-            }
-            else {
-                if ( fds[i].for_read ) {
-                    struct reader_context_s *c = find_reader (fds[i].fd,1);
-                    
-                    if (!c) { 
-                        DEBUG1 ("no reader thread for fd %d", fds[i].fd);
-                    }
-                    else {
-                        waitbuf[nwait++] = c->have_data_ev;
+        if ( fds[i].for_read || fds[i].for_write ) {
+            if ( fds[i].for_read ) {
+                struct reader_context_s *c = find_reader (fds[i].fd,1);
+                
+                if (!c) { 
+                    DEBUG1 ("oops: no reader thread for fd %d", fds[i].fd);
+                }
+                else {
+                    if ( nwait >= DIM (waitbuf) ) {
+                        DEBUG_END (dbg_help, "oops ]");
+                        DEBUG0 ("Too many objects for WFMO!" );
+                        return -1;
                     }
+                    waitidx[nwait]   = i;
+                    waitbuf[nwait++] = c->have_data_ev;
                 }
-                DEBUG_ADD2 (dbg_help, "%c%d ",
-                               fds[i].for_read? 'r':'w',fds[i].fd );
-                any = 1;
             }
+            DEBUG_ADD2 (dbg_help, "%c%d ",
+                        fds[i].for_read? 'r':'w',fds[i].fd );
+            any = 1;
         }
         fds[i].signaled = 0;
     }
@@ -651,7 +669,8 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
         any = 0;
         for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) {
             if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) {
-                fds[i].signaled = 1;
+                assert (waitidx[i] >=0 && waitidx[i] < nfds);
+                fds[waitidx[i]].signaled = 1;
                 any = 1;
                 count++;
             }
@@ -686,6 +705,19 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
         count = -1;
     }
 
+    if ( count ) {
+        DEBUG_BEGIN (dbg_help, " signaled [ ");
+        for ( i=0; i < nfds; i++ ) {
+            if ( fds[i].fd == -1 ) 
+                continue;
+            if ( (fds[i].for_read || fds[i].for_write) && fds[i].signaled ) {
+                DEBUG_ADD2 (dbg_help, "%c%d ",
+                            fds[i].for_read? 'r':'w',fds[i].fd );
+            }
+        }
+        DEBUG_END (dbg_help, "]");
+    }
+    
     return count;
 #else  /* This is the code we use */
     int i, any, count;
index 71038fb35c9acacced2c0b13e41c0af0006fa883..c0cfe133621126a10ce1063b6ac36b20c9298eea 100644 (file)
@@ -53,9 +53,6 @@ struct wait_item_s {
     void *handler_value;
     int pid;
     int inbound;       /* this is an inbound data handler fd */
-    int exited;
-    int exit_status;  
-    int exit_signal;
     GpgmeCtx ctx;
 };
 
@@ -82,51 +79,20 @@ queue_item_from_context ( GpgmeCtx ctx )
 }
 
 
-static void
-propagate_term_results ( const struct wait_item_s *first_q )
-{
-    struct wait_item_s *q;
-    int i;
-    
-    for (i=0; i < fd_table_size; i++ ) {
-        if ( fd_table[i].fd != -1 && (q=fd_table[i].opaque)
-             && q != first_q && !q->exited
-             && q->pid == first_q->pid  ) {
-            q->exited = first_q->exited;
-            q->exit_status = first_q->exit_status;
-            q->exit_signal = first_q->exit_signal;
-        }
-    }
-}
-
 static int
-count_active_fds ( int pid )
+count_active_and_thawed_fds ( int pid )
 {
     struct wait_item_s *q;
     int i, count = 0;
     
     for (i=0; i < fd_table_size; i++ ) {
         if ( fd_table[i].fd != -1 && (q=fd_table[i].opaque)
-             && q->active && q->pid == pid  ) 
+             && q->active && !fd_table[i].frozen && q->pid == pid  ) 
             count++;
     }
     return count;
 }
 
-static void
-clear_active_fds ( int pid )
-{
-    struct wait_item_s *q;
-    int i;
-    
-    for (i=0; i < fd_table_size; i++ ) {
-        if ( fd_table[i].fd != -1 && (q=fd_table[i].opaque)
-             && q->active && q->pid == pid  ) 
-            q->active = 0;
-    }
-}
-
-
 /* remove the given process from the queue */
 static void
 remove_process ( int pid )
@@ -187,28 +153,9 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
             q = queue_item_from_context ( c );
             assert (q);
             
-            if (q->exited) {
-                /* this is the second time we reached this and we got no
-                 * more data from the pipe (which may happen due to buffering).
-                 * Set all FDs inactive.
-                 */
-                clear_active_fds (q->pid);
-            }
-            else if ( _gpgme_io_waitpid (q->pid, 0,
-                                          &q->exit_status, &q->exit_signal)){
-                q->exited = 1;     
-                propagate_term_results (q);
-            }
-
-            if ( q->exited ) {
-                if ( !count_active_fds (q->pid) ) {
-                    /* Hmmm, as long as we don't have a callback for
-                     * the exit status, we have no use for these
-                     * values and therefore we can remove this from
-                     * the queue */
-                    remove_process (q->pid);
-                    hang = 0;
-                }
+            if ( !count_active_and_thawed_fds (q->pid) ) {
+                remove_process (q->pid);
+                hang = 0;
             }
         }
         if (hang)
@@ -250,6 +197,7 @@ do_select ( void )
                 any = 1;
             if ( q->active && q->handler (q->handler_value,
                                           q->pid, fd_table[i].fd ) ) {
+                DEBUG1 ("setting fd %d inactive", fd_table[i].fd );
                 q->active = 0;
                 fd_table[i].for_read = 0;
                 fd_table[i].for_write = 0;
@@ -334,7 +282,7 @@ _gpgme_freeze_fd ( int fd )
     for (i=0; i < fd_table_size; i++ ) {
         if ( fd_table[i].fd == fd ) {
             fd_table[i].frozen = 1;
-            /*fprintf (stderr, "** FD %d frozen\n", fd );*/
+            DEBUG1 ("fd %d frozen", fd );
             break;
         }
     }
@@ -350,7 +298,7 @@ _gpgme_thaw_fd ( int fd )
     for (i=0; i < fd_table_size; i++ ) {
         if ( fd_table[i].fd == fd ) {
             fd_table[i].frozen = 0;
-            /*fprintf (stderr, "** FD %d thawed\n", fd );*/
+            DEBUG1 ("fd %d thawed", fd );
             break;
         }
     }