Fixed W32 bugs and one major bug which swallowed up some output.
This commit is contained in:
parent
1316aed172
commit
1648829c39
4
TODO
4
TODO
@ -5,6 +5,4 @@
|
|||||||
* Allow to use GTK's main loop instead of the select stuff in
|
* Allow to use GTK's main loop instead of the select stuff in
|
||||||
wait.c
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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>
|
2001-01-30 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* w32-io.c (_gpgme_io_spawn): Use the supplied path arg.
|
* w32-io.c (_gpgme_io_spawn): Use the supplied path arg.
|
||||||
|
@ -139,6 +139,7 @@ _gpgme_debug_end (void **helper, const char *text)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_gpgme_debug_add (helper, "%s", text );
|
_gpgme_debug_add (helper, "%s", text );
|
||||||
|
fflush (ctl->fp); /* we need this for the buggy Windoze libc */
|
||||||
rewind (ctl->fp);
|
rewind (ctl->fp);
|
||||||
LOCK (debug_lock);
|
LOCK (debug_lock);
|
||||||
while ( (c=getc (ctl->fp)) != EOF ) {
|
while ( (c=getc (ctl->fp)) != EOF ) {
|
||||||
@ -149,6 +150,7 @@ _gpgme_debug_end (void **helper, const char *text)
|
|||||||
putc ('\n', stderr);
|
putc ('\n', stderr);
|
||||||
UNLOCK (debug_lock);
|
UNLOCK (debug_lock);
|
||||||
|
|
||||||
|
fclose (ctl->fp);
|
||||||
remove (ctl->fname);
|
remove (ctl->fname);
|
||||||
xfree (ctl);
|
xfree (ctl);
|
||||||
*helper = NULL;
|
*helper = NULL;
|
||||||
|
@ -1018,7 +1018,8 @@ read_status ( GpgObject gpg )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( r->code == STATUS_END_STREAM ) {
|
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
|
/* 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 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gpg->status.eof;
|
return gpg->colon.eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
|
@ -216,14 +216,14 @@ version_line_handler ( GpgmeCtx c, char *line )
|
|||||||
static const char *
|
static const char *
|
||||||
get_engine_info (void)
|
get_engine_info (void)
|
||||||
{
|
{
|
||||||
const char *engine_info =NULL;
|
static const char *engine_info =NULL;
|
||||||
GpgmeCtx c = NULL;
|
GpgmeCtx c = NULL;
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
const char *path = NULL;
|
const char *path = NULL;
|
||||||
|
|
||||||
/* FIXME: make sure that only one instance does run */
|
/* FIXME: make sure that only one instance does run */
|
||||||
if (engine_info)
|
if (engine_info)
|
||||||
goto leave;
|
return engine_info;
|
||||||
|
|
||||||
path = _gpgme_get_gpg_path ();
|
path = _gpgme_get_gpg_path ();
|
||||||
err = gpgme_new (&c);
|
err = gpgme_new (&c);
|
||||||
@ -299,3 +299,7 @@ get_engine_info (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,12 +58,11 @@ struct reader_context_s {
|
|||||||
DECLARE_LOCK (mutex);
|
DECLARE_LOCK (mutex);
|
||||||
|
|
||||||
int eof;
|
int eof;
|
||||||
|
int eof_shortcut;
|
||||||
int error;
|
int error;
|
||||||
int error_code;
|
int error_code;
|
||||||
|
|
||||||
HANDLE have_data_ev; /* manually reset */
|
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 */
|
HANDLE have_space_ev; /* auto reset */
|
||||||
size_t readpos, writepos;
|
size_t readpos, writepos;
|
||||||
char buffer[READBUF_SIZE];
|
char buffer[READBUF_SIZE];
|
||||||
@ -128,10 +127,17 @@ reader (void *arg)
|
|||||||
DEBUG2 ("reader thread %p: reading %d bytes", c->thread_hd, nbytes );
|
DEBUG2 ("reader thread %p: reading %d bytes", c->thread_hd, nbytes );
|
||||||
if ( !ReadFile ( c->file_hd,
|
if ( !ReadFile ( c->file_hd,
|
||||||
c->buffer+c->writepos, nbytes, &nread, NULL) ) {
|
c->buffer+c->writepos, nbytes, &nread, NULL) ) {
|
||||||
c->error = 1;
|
|
||||||
c->error_code = (int)GetLastError ();
|
c->error_code = (int)GetLastError ();
|
||||||
|
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",
|
DEBUG2 ("reader thread %p: read error: ec=%d",
|
||||||
c->thread_hd, c->error_code );
|
c->thread_hd, c->error_code );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !nread ) {
|
if ( !nread ) {
|
||||||
@ -143,10 +149,11 @@ reader (void *arg)
|
|||||||
|
|
||||||
LOCK (c->mutex);
|
LOCK (c->mutex);
|
||||||
c->writepos = (c->writepos + nread) % READBUF_SIZE;
|
c->writepos = (c->writepos + nread) % READBUF_SIZE;
|
||||||
c->have_data_flag = 1;
|
|
||||||
SetEvent (c->have_data_ev);
|
SetEvent (c->have_data_ev);
|
||||||
UNLOCK (c->mutex);
|
UNLOCK (c->mutex);
|
||||||
}
|
}
|
||||||
|
/* indicate that we have an error or eof */
|
||||||
|
SetEvent (c->have_data_ev);
|
||||||
DEBUG1 ("reader thread %p ended", c->thread_hd );
|
DEBUG1 ("reader thread %p ended", c->thread_hd );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -245,20 +252,33 @@ _gpgme_io_read ( int fd, void *buffer, size_t count )
|
|||||||
DEBUG0 ( "no reader thread\n");
|
DEBUG0 ( "no reader thread\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (c->eof_shortcut) {
|
||||||
|
DEBUG1 ("fd %d: EOF (again)", fd );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
LOCK (c->mutex);
|
LOCK (c->mutex);
|
||||||
if (c->readpos == c->writepos) { /* no data avail */
|
if (c->readpos == c->writepos && !c->error) { /*no data avail*/
|
||||||
UNLOCK (c->mutex);
|
UNLOCK (c->mutex);
|
||||||
DEBUG2 ("fd %d: waiting for data from thread %p", fd, c->thread_hd);
|
DEBUG2 ("fd %d: waiting for data from thread %p", fd, c->thread_hd);
|
||||||
WaitForSingleObject (c->have_data_ev, INFINITE);
|
WaitForSingleObject (c->have_data_ev, INFINITE);
|
||||||
DEBUG2 ("fd %d: data from thread %p available", fd, c->thread_hd);
|
DEBUG2 ("fd %d: data from thread %p available", fd, c->thread_hd);
|
||||||
LOCK (c->mutex);
|
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
|
nread = c->readpos < c->writepos? c->writepos - c->readpos
|
||||||
@ -267,11 +287,9 @@ _gpgme_io_read ( int fd, void *buffer, size_t count )
|
|||||||
nread = count;
|
nread = count;
|
||||||
memcpy (buffer, c->buffer+c->readpos, nread);
|
memcpy (buffer, c->buffer+c->readpos, nread);
|
||||||
c->readpos = (c->readpos + nread) % READBUF_SIZE;
|
c->readpos = (c->readpos + nread) % READBUF_SIZE;
|
||||||
if (c->readpos == c->writepos) {
|
if (c->readpos == c->writepos && !c->eof) {
|
||||||
c->have_data_flag = 0;
|
|
||||||
ResetEvent (c->have_data_ev);
|
ResetEvent (c->have_data_ev);
|
||||||
}
|
}
|
||||||
if (nread)
|
|
||||||
SetEvent (c->have_space_ev);
|
SetEvent (c->have_space_ev);
|
||||||
UNLOCK (c->mutex);
|
UNLOCK (c->mutex);
|
||||||
|
|
||||||
@ -287,9 +305,9 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
|
|||||||
DWORD nwritten;
|
DWORD nwritten;
|
||||||
HANDLE h = fd_to_handle (fd);
|
HANDLE h = fd_to_handle (fd);
|
||||||
|
|
||||||
#warning writing blocks for large counts, so we limit it here.
|
/* writing blocks for large counts, so we limit it here. */
|
||||||
if (count > 500)
|
if (count > 1024)
|
||||||
count = 500;
|
count = 1024;
|
||||||
|
|
||||||
DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count );
|
DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count );
|
||||||
if ( !WriteFile ( h, buffer, count, &nwritten, NULL) ) {
|
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
|
#if 1
|
||||||
HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
|
HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
|
||||||
|
int waitidx[MAXIMUM_WAIT_OBJECTS];
|
||||||
int code, nwait;
|
int code, nwait;
|
||||||
int i, any, any_write;
|
int i, any, any_write;
|
||||||
int count;
|
int count;
|
||||||
@ -599,20 +618,20 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
|||||||
for ( i=0; i < nfds; i++ ) {
|
for ( i=0; i < nfds; i++ ) {
|
||||||
if ( fds[i].fd == -1 )
|
if ( fds[i].fd == -1 )
|
||||||
continue;
|
continue;
|
||||||
|
if ( fds[i].for_read || fds[i].for_write ) {
|
||||||
if ( fds[i].for_read ) {
|
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) ) {
|
if ( nwait >= DIM (waitbuf) ) {
|
||||||
DEBUG_END (dbg_help, "oops ]");
|
DEBUG_END (dbg_help, "oops ]");
|
||||||
DEBUG0 ("Too many objects for WFMO!" );
|
DEBUG0 ("Too many objects for WFMO!" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
waitidx[nwait] = i;
|
||||||
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;
|
waitbuf[nwait++] = c->have_data_ev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -620,7 +639,6 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
|||||||
fds[i].for_read? 'r':'w',fds[i].fd );
|
fds[i].for_read? 'r':'w',fds[i].fd );
|
||||||
any = 1;
|
any = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fds[i].signaled = 0;
|
fds[i].signaled = 0;
|
||||||
}
|
}
|
||||||
DEBUG_END (dbg_help, "]");
|
DEBUG_END (dbg_help, "]");
|
||||||
@ -651,7 +669,8 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
|||||||
any = 0;
|
any = 0;
|
||||||
for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) {
|
for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) {
|
||||||
if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) {
|
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;
|
any = 1;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -686,6 +705,19 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
|||||||
count = -1;
|
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;
|
return count;
|
||||||
#else /* This is the code we use */
|
#else /* This is the code we use */
|
||||||
int i, any, count;
|
int i, any, count;
|
||||||
|
64
gpgme/wait.c
64
gpgme/wait.c
@ -53,9 +53,6 @@ struct wait_item_s {
|
|||||||
void *handler_value;
|
void *handler_value;
|
||||||
int pid;
|
int pid;
|
||||||
int inbound; /* this is an inbound data handler fd */
|
int inbound; /* this is an inbound data handler fd */
|
||||||
int exited;
|
|
||||||
int exit_status;
|
|
||||||
int exit_signal;
|
|
||||||
GpgmeCtx ctx;
|
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
|
static int
|
||||||
count_active_fds ( int pid )
|
count_active_and_thawed_fds ( int pid )
|
||||||
{
|
{
|
||||||
struct wait_item_s *q;
|
struct wait_item_s *q;
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
|
|
||||||
for (i=0; i < fd_table_size; i++ ) {
|
for (i=0; i < fd_table_size; i++ ) {
|
||||||
if ( fd_table[i].fd != -1 && (q=fd_table[i].opaque)
|
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++;
|
count++;
|
||||||
}
|
}
|
||||||
return 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 */
|
/* remove the given process from the queue */
|
||||||
static void
|
static void
|
||||||
remove_process ( int pid )
|
remove_process ( int pid )
|
||||||
@ -187,30 +153,11 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
|
|||||||
q = queue_item_from_context ( c );
|
q = queue_item_from_context ( c );
|
||||||
assert (q);
|
assert (q);
|
||||||
|
|
||||||
if (q->exited) {
|
if ( !count_active_and_thawed_fds (q->pid) ) {
|
||||||
/* 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);
|
remove_process (q->pid);
|
||||||
hang = 0;
|
hang = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (hang)
|
if (hang)
|
||||||
run_idle ();
|
run_idle ();
|
||||||
} while (hang && !c->cancel );
|
} while (hang && !c->cancel );
|
||||||
@ -250,6 +197,7 @@ do_select ( void )
|
|||||||
any = 1;
|
any = 1;
|
||||||
if ( q->active && q->handler (q->handler_value,
|
if ( q->active && q->handler (q->handler_value,
|
||||||
q->pid, fd_table[i].fd ) ) {
|
q->pid, fd_table[i].fd ) ) {
|
||||||
|
DEBUG1 ("setting fd %d inactive", fd_table[i].fd );
|
||||||
q->active = 0;
|
q->active = 0;
|
||||||
fd_table[i].for_read = 0;
|
fd_table[i].for_read = 0;
|
||||||
fd_table[i].for_write = 0;
|
fd_table[i].for_write = 0;
|
||||||
@ -334,7 +282,7 @@ _gpgme_freeze_fd ( int fd )
|
|||||||
for (i=0; i < fd_table_size; i++ ) {
|
for (i=0; i < fd_table_size; i++ ) {
|
||||||
if ( fd_table[i].fd == fd ) {
|
if ( fd_table[i].fd == fd ) {
|
||||||
fd_table[i].frozen = 1;
|
fd_table[i].frozen = 1;
|
||||||
/*fprintf (stderr, "** FD %d frozen\n", fd );*/
|
DEBUG1 ("fd %d frozen", fd );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,7 +298,7 @@ _gpgme_thaw_fd ( int fd )
|
|||||||
for (i=0; i < fd_table_size; i++ ) {
|
for (i=0; i < fd_table_size; i++ ) {
|
||||||
if ( fd_table[i].fd == fd ) {
|
if ( fd_table[i].fd == fd ) {
|
||||||
fd_table[i].frozen = 0;
|
fd_table[i].frozen = 0;
|
||||||
/*fprintf (stderr, "** FD %d thawed\n", fd );*/
|
DEBUG1 ("fd %d thawed", fd );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user