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 { ...@@ -28,6 +28,7 @@ client c1 {
logexpect l1 -v v1 -g vxid -d 1 -q Error { logexpect l1 -v v1 -g vxid -d 1 -q Error {
expect 0 * Begin {^req \d+ rxreq$} expect 0 * Begin {^req \d+ rxreq$}
expect * = Error {^vdfp_pipe: vdp cat: ${cat} stderr: } expect * = Error {^vdfp_pipe: vdp cat: ${cat} stderr: }
expect * = Error {^vdfp_pipe: vdp cat: ${cat} exited with status 1}
expect * = End expect * = End
} -run } -run
......
...@@ -84,7 +84,7 @@ struct VPFX(pipe_vdp) { ...@@ -84,7 +84,7 @@ struct VPFX(pipe_vdp) {
struct vdp *vdp; struct vdp *vdp;
char **argv; char **argv;
struct setenv_head *setenv_head; struct setenv_head *setenv_head;
size_t bufsz; ssize_t bufsz;
int argc; int argc;
int tmo_ms; int tmo_ms;
}; };
...@@ -379,6 +379,7 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv, ...@@ -379,6 +379,7 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
int retval; int retval;
ssize_t nbytes; ssize_t nbytes;
struct VPFX(pipe_vdp) *obj; struct VPFX(pipe_vdp) *obj;
enum vdp_action act_bytes = VDP_FLUSH;
CHECK_OBJ_NOTNULL(ctx, VDP_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VDP_CTX_MAGIC);
assert(len >= 0); assert(len >= 0);
...@@ -391,14 +392,14 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv, ...@@ -391,14 +392,14 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
AN(obj->bufsz); AN(obj->bufsz);
fds = state->fds; fds = state->fds;
if (act == VDP_END && len == 0)
closefd(&fds[STDIN_FILENO].fd);
for (;;) { for (;;) {
fds[STDIN_FILENO].revents = 0; fds[STDIN_FILENO].revents = 0;
fds[STDOUT_FILENO].revents = 0; fds[STDOUT_FILENO].revents = 0;
fds[STDERR_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; errno = 0;
retval = poll(fds, 3, obj->tmo_ms); retval = poll(fds, 3, obj->tmo_ms);
if (retval < 0) { if (retval < 0) {
...@@ -452,14 +453,18 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv, ...@@ -452,14 +453,18 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
assert(i == STDOUT_FILENO || i == STDERR_FILENO); assert(i == STDOUT_FILENO || i == STDERR_FILENO);
if (!(fds[i].revents & POLLIN)) { if (!(fds[i].revents & POLLIN)) {
AN(fds[i].revents & POLLHUP); AN(fds[i].revents & POLLHUP);
if (i == STDOUT_FILENO) if (i == STDERR_FILENO) {
closefd(&fds[STDOUT_FILENO].fd);
else
closefd(&fds[STDERR_FILENO].fd); closefd(&fds[STDERR_FILENO].fd);
continue;
}
closefd(&fds[STDOUT_FILENO].fd);
if (act_bytes != VDP_END)
VDP_bytes(ctx, VDP_END, NULL, 0);
continue; continue;
} }
errno = 0; errno = 0;
nbytes = read(fds[i].fd, state->buf, obj->bufsz); nbytes = read(fds[i].fd, state->buf, obj->bufsz);
if (nbytes < 0) { if (nbytes < 0) {
VSLb(ctx->vsl, SLT_Error, "vdfp_pipe: vdp %s:" VSLb(ctx->vsl, SLT_Error, "vdfp_pipe: vdp %s:"
" error reading %s from %s: %s", " error reading %s from %s: %s",
...@@ -468,15 +473,19 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv, ...@@ -468,15 +473,19 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
close_all(fds); close_all(fds);
return (-1); return (-1);
} }
if (i == STDOUT_FILENO &&
fds[i].revents & POLLHUP &&
nbytes < obj->bufsz) {
act_bytes = VDP_END;
}
if (nbytes == 0) { if (nbytes == 0) {
if (i == STDOUT_FILENO) if (i == STDOUT_FILENO)
closefd(&fds[STDOUT_FILENO].fd); closefd(&fds[STDOUT_FILENO].fd);
else else
closefd(&fds[STDERR_FILENO].fd); closefd(&fds[STDERR_FILENO].fd);
continue;
} }
if (i == STDOUT_FILENO) { if (i == STDOUT_FILENO) {
retval = VDP_bytes(ctx, VDP_FLUSH, state->buf, retval = VDP_bytes(ctx, act_bytes, state->buf,
nbytes); nbytes);
if (retval < 0) { if (retval < 0) {
close_all(fds); close_all(fds);
...@@ -507,13 +516,9 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv, ...@@ -507,13 +516,9 @@ vdp_bytes(struct vdp_ctx *ctx, enum vdp_action act, void **priv,
errmsg += (linelen + 1); errmsg += (linelen + 1);
} }
} }
if (act == VDP_END) { if (act == VDP_END && fds[STDOUT_FILENO].fd != -1)
if (fds[STDIN_FILENO].fd != -1 && len == 0) continue;
closefd(&fds[STDIN_FILENO].fd);
if (fds[STDOUT_FILENO].fd != -1 ||
fds[STDERR_FILENO].fd != -1)
continue;
}
if (len == 0) if (len == 0)
break; 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