diff options
-rw-r--r-- | src/ChangeLog | 15 | ||||
-rw-r--r-- | src/assuan-buffer.c | 7 | ||||
-rw-r--r-- | src/assuan-defs.h | 11 | ||||
-rw-r--r-- | src/assuan-handler.c | 24 | ||||
-rw-r--r-- | src/assuan-pipe-connect.c | 19 | ||||
-rw-r--r-- | src/assuan-uds.c | 49 |
6 files changed, 58 insertions, 67 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c88d4c1..d309e58 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2009-11-10 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (struct assuan_context_s): Rename + CTX->process_done to CTX->process_complete for clarity. Remove + buffer variables from UDS. + * assuan-pipe-connect.c (socketpair_connect): Allow FD_CHILD_LIST + to be NULL. + * assuan-handler.c: Rename CTX->process_done to + CTX->process_complete for clarity. + (process_request, process_next): Handle EOF. + * assuan-uds.c (uds_reader): Remove buffering, which breaks the + pending line algorithm in assuan-buffer.c. + (_assuan_init_uds_io, _assuan_uds_deinit): Remove buffering. + * assuan-buffer.c (_assuan_read_line): Add comment. + 2009-11-05 Marcus Brinkmann <marcus@g10code.de> * assuan.h (struct _assuan_peercred, assuan_peercred_t): New. diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c index 32a9aee..8dac4fb 100644 --- a/src/assuan-buffer.c +++ b/src/assuan-buffer.c @@ -79,6 +79,7 @@ readline (assuan_context_t ctx, char *buf, size_t buflen, *r_eof = 1; break; /* allow incomplete lines */ } + p = buf; nleft -= n; buf += n; @@ -88,7 +89,6 @@ readline (assuan_context_t ctx, char *buf, size_t buflen, if (p) break; /* at least one full line available - that's enough for now */ } - return 0; } @@ -142,7 +142,9 @@ _assuan_read_line (assuan_context_t ctx) if (saved_errno == EAGAIN) { - /* We have to save a partial line. */ + /* We have to save a partial line. Due to readline's + behaviour, we know that this is not a complete line yet + (no newline). So we don't set PENDING to true. */ memcpy (ctx->inbound.attic.line, line, atticlen + nread); ctx->inbound.attic.pending = 0; ctx->inbound.attic.linelen = atticlen + nread; @@ -253,6 +255,7 @@ assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen) *line = ctx->inbound.line; *linelen = ctx->inbound.linelen; + return err; } diff --git a/src/assuan-defs.h b/src/assuan-defs.h index 8ce5f99..00a3652 100644 --- a/src/assuan-defs.h +++ b/src/assuan-defs.h @@ -127,7 +127,7 @@ struct assuan_context_s int is_server; /* Set if this is context belongs to a server */ int in_inquire; int in_process_next; - int process_done; + int process_complete; int in_command; /* The following members are used by assuan_inquire_ext. */ @@ -176,15 +176,8 @@ struct assuan_context_s struct sockaddr_un myaddr; struct sockaddr_un serveraddr; - /* Structure used for unix domain socket buffering. FIXME: We don't - use datagrams anymore thus we could get away with a simpler - buffering approach. */ + /* Structure used for unix domain sockets. */ struct { - void *buffer; /* Malloced buffer. */ - int bufferallocated; /* Memory allocated. */ - int bufferoffset; /* Offset of start of buffer. */ - int buffersize; /* Bytes buffered. */ - assuan_fd_t pendingfds[5]; /* Array to save received descriptors. */ int pendingfdscount; /* Number of received descriptors. */ } uds; diff --git a/src/assuan-handler.c b/src/assuan-handler.c index a46e7f7..a9cc2bd 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -125,7 +125,7 @@ std_handler_bye (assuan_context_t ctx, char *line) assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); /* pretty simple :-) */ - ctx->process_done = 1; + ctx->process_complete = 1; return PROCESS_DONE (ctx, 0); } @@ -593,7 +593,7 @@ assuan_process_done (assuan_context_t ctx, gpg_error_t rc) /* Error handling. */ if (!rc) { - if (ctx->process_done) + if (ctx->process_complete) { /* No error checking because the peer may have already disconnect. */ @@ -643,6 +643,11 @@ process_next (assuan_context_t ctx) rc = _assuan_read_line (ctx); if (_assuan_error_is_eagain (ctx, rc)) return 0; + if (gpg_err_code (rc) == GPG_ERR_EOF) + { + ctx->process_complete = 1; + return 0; + } if (rc) return rc; if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) @@ -698,15 +703,15 @@ assuan_process_next (assuan_context_t ctx, int *done) if (done) *done = 0; - ctx->process_done = 0; + ctx->process_complete = 0; do { rc = process_next (ctx); } - while (!rc && !ctx->process_done && assuan_pending_line (ctx)); + while (!rc && !ctx->process_complete && assuan_pending_line (ctx)); if (done) - *done = !!ctx->process_done; + *done = !!ctx->process_complete; return rc; } @@ -726,6 +731,11 @@ process_request (assuan_context_t ctx) rc = _assuan_read_line (ctx); } while (_assuan_error_is_eagain (ctx, rc)); + if (gpg_err_code (rc) == GPG_ERR_EOF) + { + ctx->process_complete = 1; + return 0; + } if (rc) return rc; if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) @@ -756,10 +766,10 @@ assuan_process (assuan_context_t ctx) { gpg_error_t rc; - ctx->process_done = 0; + ctx->process_complete = 0; do { rc = process_request (ctx); - } while (!rc && !ctx->process_done); + } while (!rc && !ctx->process_complete); return rc; } diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index 6c7762e..9e214a8 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -317,12 +317,15 @@ socketpair_connect (assuan_context_t ctx, sprintf (mypidstr, "%lu", (unsigned long)getpid ()); - while (fd_child_list[child_fds_cnt] != ASSUAN_INVALID_FD) - child_fds_cnt++; + if (fd_child_list) + while (fd_child_list[child_fds_cnt] != ASSUAN_INVALID_FD) + child_fds_cnt++; child_fds = _assuan_malloc (ctx, (child_fds_cnt + 2) * sizeof (int)); if (! child_fds) return TRACE_ERR (gpg_err_code_from_syserror ()); - memcpy (&child_fds[1], fd_child_list, (child_fds_cnt + 1) * sizeof (int)); + child_fds[1] = ASSUAN_INVALID_FD; + if (fd_child_list) + memcpy (&child_fds[1], fd_child_list, (child_fds_cnt + 1) * sizeof (int)); if (_assuan_socketpair (ctx, AF_LOCAL, SOCK_STREAM, 0, fds)) { @@ -333,7 +336,6 @@ socketpair_connect (assuan_context_t ctx, atp.peer_fd = fds[1]; child_fds[0] = fds[1]; - rc = _assuan_spawn (ctx, &pid, name, argv, ASSUAN_INVALID_FD, ASSUAN_INVALID_FD, child_fds, at_socketpair_fork_cb, &atp, 0); @@ -351,9 +353,12 @@ socketpair_connect (assuan_context_t ctx, of the peer socketpair fd (fd_child_list[0]) must be done by the wrapper program based on the environment variable _assuan_connection_fd. */ - for (idx = 0; fd_child_list[idx] != -1; idx++) - /* We add 1 to skip over the socketpair end. */ - fd_child_list[idx] = child_fds[idx + 1]; + if (fd_child_list) + { + for (idx = 0; fd_child_list[idx] != -1; idx++) + /* We add 1 to skip over the socketpair end. */ + fd_child_list[idx] = child_fds[idx + 1]; + } /* If this is the server child process, exit early. */ if (! name && (*argv)[0] == 's') diff --git a/src/assuan-uds.c b/src/assuan-uds.c index 2bec03d..4b9988f 100644 --- a/src/assuan-uds.c +++ b/src/assuan-uds.c @@ -64,24 +64,15 @@ #endif /*USE_DESCRIPTOR_PASSING*/ -/* Read from a unix domain socket using sendmsg. - - FIXME: We don't need the buffering. It is a leftover from the time - when we used datagrams. */ +/* Read from a unix domain socket using sendmsg. */ static ssize_t uds_reader (assuan_context_t ctx, void *buf, size_t buflen) { #ifndef HAVE_W32_SYSTEM - int len = ctx->uds.buffersize; - - if (!ctx->uds.bufferallocated) - { - ctx->uds.buffer = _assuan_malloc (ctx, 2048); - if (!ctx->uds.buffer) - return gpg_error_from_syserror (); - ctx->uds.bufferallocated = 2048; - } - + int len = 0; + /* This loop should be OK. As FDs are followed by data, the + readable status of the socket does not change and no new + select/event-loop round is necessary. */ while (!len) /* No data is buffered. */ { struct msghdr msg; @@ -100,8 +91,8 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen) msg.msg_namelen = 0; msg.msg_iov = &iovec; msg.msg_iovlen = 1; - iovec.iov_base = ctx->uds.buffer; - iovec.iov_len = ctx->uds.bufferallocated; + iovec.iov_base = buf; + iovec.iov_len = buflen; #ifdef USE_DESCRIPTOR_PASSING msg.msg_control = control_u.control; msg.msg_controllen = sizeof (control_u.control); @@ -113,9 +104,6 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen) if (len == 0) return 0; - ctx->uds.buffersize = len; - ctx->uds.bufferoffset = 0; - #ifdef USE_DESCRIPTOR_PASSING cmptr = CMSG_FIRSTHDR (&msg); if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int))) @@ -142,17 +130,6 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen) #endif /*USE_DESCRIPTOR_PASSING*/ } - /* Return some data to the user. */ - - if (len > buflen) /* We have more than the user requested. */ - len = buflen; - - memcpy (buf, (char*)ctx->uds.buffer + ctx->uds.bufferoffset, len); - ctx->uds.buffersize -= len; - assert (ctx->uds.buffersize >= 0); - ctx->uds.bufferoffset += len; - assert (ctx->uds.bufferoffset <= ctx->uds.bufferallocated); - return len; #else /*HAVE_W32_SYSTEM*/ int res = recvfrom (HANDLE2SOCKET(ctx->inbound.fd), buf, buflen, 0, NULL, NULL); @@ -291,14 +268,6 @@ _assuan_uds_deinit (assuan_context_t ctx) { /* First call the finish_handler which should close descriptors etc. */ ctx->finish_handler (ctx); - - if (ctx->uds.buffer) - { - assert (ctx->uds.bufferallocated); - ctx->uds.bufferallocated = 0; - _assuan_free (ctx, ctx->uds.buffer); - } - _assuan_uds_close_fds (ctx); } @@ -312,10 +281,6 @@ _assuan_init_uds_io (assuan_context_t ctx) ctx->engine.sendfd = uds_sendfd; ctx->engine.receivefd = uds_receivefd; - ctx->uds.buffer = 0; - ctx->uds.bufferoffset = 0; - ctx->uds.buffersize = 0; - ctx->uds.bufferallocated = 0; ctx->uds.pendingfdscount = 0; } |