Improve VDP_END handling

- ensure we do send VDP_END down
- try to send it with the last bytes (POLLHUP present
  with a read smaller than the buffer size)
parent 0b12aa09
......@@ -28,6 +28,7 @@ client c1 {
logexpect l1 -v v1 -g vxid -d 1 -q Error {
expect 0 * Begin {^req \d+ rxreq$}
expect * = Error {^vdfp_pipe: vdp cat: ${cat} stderr: }
expect * = Error {^vdfp_pipe: vdp cat: ${cat} exited with status 1}
expect * = End
} -run
......
......@@ -84,7 +84,7 @@ struct VPFX(pipe_vdp) {
struct vdp *vdp;
char **argv;
struct setenv_head *setenv_head;
size_t bufsz;
ssize_t bufsz;
int argc;
int tmo_ms;
};
......@@ -379,6 +379,7 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
int retval;
ssize_t nbytes;
struct VPFX(pipe_vdp) *obj;
enum vdp_action act_bytes = VDP_FLUSH;
CHECK_OBJ_NOTNULL(ctx, VDP_CTX_MAGIC);
assert(len >= 0);
......@@ -391,14 +392,14 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
AN(obj->bufsz);
fds = state->fds;
if (act == VDP_END && len == 0)
closefd(&fds[STDIN_FILENO].fd);
for (;;) {
fds[STDIN_FILENO].revents = 0;
fds[STDOUT_FILENO].revents = 0;
fds[STDERR_FILENO].revents = 0;
if (len == 0 && act == VDP_END && fds[STDIN_FILENO].fd != -1)
closefd(&fds[STDIN_FILENO].fd);
errno = 0;
retval = poll(fds, 3, obj->tmo_ms);
if (retval < 0) {
......@@ -452,14 +453,18 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
assert(i == STDOUT_FILENO || i == STDERR_FILENO);
if (!(fds[i].revents & POLLIN)) {
AN(fds[i].revents & POLLHUP);
if (i == STDOUT_FILENO)
closefd(&fds[STDOUT_FILENO].fd);
else
if (i == STDERR_FILENO) {
closefd(&fds[STDERR_FILENO].fd);
continue;
}
closefd(&fds[STDOUT_FILENO].fd);
if (act_bytes != VDP_END)
VDP_bytes(ctx, VDP_END, NULL, 0);
continue;
}
errno = 0;
nbytes = read(fds[i].fd, state->buf, obj->bufsz);
if (nbytes < 0) {
VSLb(ctx->vsl, SLT_Error, "vdfp_pipe: vdp %s:"
" error reading %s from %s: %s",
......@@ -468,15 +473,19 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
close_all(fds);
return (-1);
}
if (i == STDOUT_FILENO &&
fds[i].revents & POLLHUP &&
nbytes < obj->bufsz) {
act_bytes = VDP_END;
}
if (nbytes == 0) {
if (i == STDOUT_FILENO)
closefd(&fds[STDOUT_FILENO].fd);
else
closefd(&fds[STDERR_FILENO].fd);
continue;
}
if (i == STDOUT_FILENO) {
retval = VDP_bytes(ctx, VDP_FLUSH, state->buf,
retval = VDP_bytes(ctx, act_bytes, state->buf,
nbytes);
if (retval < 0) {
close_all(fds);
......@@ -507,13 +516,9 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
errmsg += (linelen + 1);
}
}
if (act == VDP_END) {
if (fds[STDIN_FILENO].fd != -1 && len == 0)
closefd(&fds[STDIN_FILENO].fd);
if (fds[STDOUT_FILENO].fd != -1 ||
fds[STDERR_FILENO].fd != -1)
continue;
}
if (act == VDP_END && fds[STDOUT_FILENO].fd != -1)
continue;
if (len == 0)
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment