Commit 1c2fbb9e authored by Vladimír Čunát's avatar Vladimír Čunát

main ipc_activity: misc improvements

Stop IPC after getting an error.  One point is the situation when one
of the forks ends for some reason, which lead to problems.
Another point is pipes getting out of sync.

Smaller changes:
- don't free the handle while it's still half-in-use
- don't fully panic here because of ENOMEM, just stop IPC

Fixes knot/knot-resolver#150
parent fe7b7381
......@@ -8,6 +8,10 @@ Incompatible changes
'hasflag' and 'resolved'.
You can instead write code like qry.flags.NO_0X20 = true.
Bugfixes
--------
- fix exiting one of multiple forks (#150)
Improvements
------------
- policy.suffix: update the aho-corasick code (#200)
......
......@@ -189,11 +189,6 @@ static void tty_accept(uv_stream_t *master, int status)
}
}
static void ipc_close(uv_handle_t *handle)
{
free(handle);
}
/* @internal AF_LOCAL reads may still be interrupted, loop it. */
static bool ipc_readall(int fd, char *dst, size_t len)
{
......@@ -214,7 +209,6 @@ static void ipc_activity(uv_poll_t *handle, int status, int events)
struct engine *engine = handle->data;
if (status != 0) {
kr_log_error("[system] ipc: %s\n", uv_strerror(status));
ipc_close((uv_handle_t *)handle);
return;
}
/* Get file descriptor from handle */
......@@ -232,9 +226,7 @@ static void ipc_activity(uv_poll_t *handle, int status, int events)
errno = EINVAL;
}
if (!rbuf) {
kr_log_error("[system] ipc: %s\n", strerror(errno));
engine_stop(engine); /* Panic and stop this fork. */
return;
goto failure;
}
if (!ipc_readall(fd, rbuf, len)) {
goto failure;
......@@ -246,17 +238,22 @@ static void ipc_activity(uv_poll_t *handle, int status, int events)
if (ret > 0) {
message = lua_tostring(engine->L, -1);
}
/* Clear the Lua stack */
lua_settop(engine->L, 0);
/* Send response back */
len = strlen(message);
if (write(fd, &len, sizeof(len)) != sizeof(len) ||
write(fd, message, len) != len) {
kr_log_error("[system] ipc: %s\n", strerror(errno));
goto failure;
}
/* Clear the Lua stack */
lua_settop(engine->L, 0);
return;
return; /* success! */
failure:
kr_log_error("[system] ipc: %s\n", strerror(errno));
/* Note that if the piped command got read or written partially,
* we would get out of sync and only receive rubbish now.
* Therefore we prefer to stop IPC, but we try to continue with all else.
*/
kr_log_error("[system] stopping ipc because of: %s\n", strerror(errno));
uv_poll_stop(handle);
}
static bool ipc_watch(uv_loop_t *loop, struct engine *engine, int fd)
......
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