server_client_push_stderr(struct client *c)
{
	struct msg_stderr_data data;
	size_t		       sent, left;

	if (c->stderr_data == c->stdout_data) {
		server_client_push_stdout(c);
		return;
	}

	left = EVBUFFER_LENGTH(c->stderr_data);
	while (left != 0) {
		sent = left;
		if (sent > sizeof data.data)
			sent = sizeof data.data;
		memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent);
		data.size = sent;

		if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0)
			break;
		evbuffer_drain(c->stderr_data, sent);

		left = EVBUFFER_LENGTH(c->stderr_data);
		log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
		    sent, left);
	}
	if (left != 0) {
		c->references++;
		event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL);
		log_debug("%s: client %p, queued", __func__, c);
	}
}
server_client_push_stderr(struct client *c)
{
	struct msg_stderr_data data;
	size_t		       sent, left;

	if (c->stderr_data == c->stdout_data) {
		server_client_push_stdout(c);
		return;
	}

	left = EVBUFFER_LENGTH(c->stderr_data);
	while (left != 0) {
		sent = left;
		if (sent > sizeof data.data)
			sent = sizeof data.data;
		memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent);
		data.size = sent;

		if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0)
			break;
		evbuffer_drain(c->stderr_data, sent);

		left = EVBUFFER_LENGTH(c->stderr_data);
		log_debug("%s: client %p, sent %zu, left %zu", __func__, c,
		    sent, left);
	}
	if (left != 0) {
		c->references++;
		event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL);
		log_debug("%s: client %p, queued", __func__, c);
	}
}