summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog15
-rw-r--r--src/assuan-buffer.c7
-rw-r--r--src/assuan-defs.h11
-rw-r--r--src/assuan-handler.c24
-rw-r--r--src/assuan-pipe-connect.c19
-rw-r--r--src/assuan-uds.c49
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;
}