X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=client_common.c;h=78b232dbd043caf1dc0ee6ba58b3437000e0d86a;hp=ff351e8902e42fba250345878d60d7d55df1db62;hb=3f1510c31beb5c053d2f6c510f04a1e7466fce65;hpb=aa3fe79526bbce17f5ceec4d9c2d2246f01d6828 diff --git a/client_common.c b/client_common.c index ff351e89..78b232db 100644 --- a/client_common.c +++ b/client_common.c @@ -48,8 +48,7 @@ void client_disconnect(struct client_task *ct) ct->scc.recv = NULL; sc_free(ct->scc.send); ct->scc.send = NULL; - btr_free_node(ct->btrn); - ct->btrn = NULL; + btr_remove_node(&ct->btrn); } /** @@ -240,6 +239,54 @@ static char **parse_features(char *buf) return features; } +static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb) +{ + int ret; + const char *designator[] = {SB_DESIGNATORS_ARRAY}; + + if (!sbb) + return 0; + if (sbb->band < NUM_SB_DESIGNATORS) + PARA_DEBUG_LOG("band: %s\n", designator[sbb->band]); + + switch (sbb->band) { + case SBD_OUTPUT: + if (iov_valid(&sbb->iov)) + btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len, + ct->btrn); + ret = 1; + goto out; + case SBD_DEBUG_LOG: + case SBD_INFO_LOG: + case SBD_NOTICE_LOG: + case SBD_WARNING_LOG: + case SBD_ERROR_LOG: + case SBD_CRIT_LOG: + case SBD_EMERG_LOG: + if (iov_valid(&sbb->iov)) { + int ll = sbb->band - SBD_DEBUG_LOG; + para_log(ll, "remote: %s", (char *)sbb->iov.iov_base); + } + ret = 1; + goto deallocate; + case SBD_EXIT__SUCCESS: + ret = -E_SERVER_CMD_SUCCESS; + goto deallocate; + case SBD_EXIT__FAILURE: + ret = -E_SERVER_CMD_FAILURE; + goto deallocate; + default: + PARA_ERROR_LOG("invalid band %d\n", sbb->band); + ret = -E_BAD_BAND; + goto deallocate; + } +deallocate: + free(sbb->iov.iov_base); +out: + sbb->iov.iov_base = NULL; + return ret; +} + static bool has_feature(const char *feature, struct client_task *ct) { return find_arg(feature, ct->features) >= 0? true : false; @@ -286,7 +333,9 @@ static void client_post_select(struct sched *s, struct task *t) size_t n; char buf[CLIENT_BUFSIZE]; - t->error = 0; + ret = task_get_notification(t); + if (ret < 0) + goto out; if (ct->scc.fd < 0) return; switch (ct->status) { @@ -430,6 +479,20 @@ static void client_post_select(struct sched *s, struct task *t) case CL_SENT_COMMAND: { char *buf2; + if (ct->use_sideband) { + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret <= 0) + goto out; + if (sbb.band == SBD_AWAITING_DATA) { + ct->status = CL_SENDING; + free(sbb.iov.iov_base); + goto out; + } + ct->status = CL_RECEIVING; + ret = dispatch_sbb(ct, &sbb); + goto out; + } /* can not use "buf" here because we need a malloced buffer */ buf2 = para_malloc(CLIENT_BUFSIZE); ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); @@ -477,6 +540,13 @@ static void client_post_select(struct sched *s, struct task *t) */ if (!FD_ISSET(ct->scc.fd, &s->rfds)) return; + if (ct->use_sideband) { + struct sb_buffer sbb; + ret = recv_sb(ct, &s->rfds, &sbb); + if (ret > 0) + ret = dispatch_sbb(ct, &sbb); + goto out; + } buf2 = para_malloc(CLIENT_BUFSIZE); ret = client_recv_buffer(ct, &s->rfds, buf2, CLIENT_BUFSIZE, &n); if (n > 0) { @@ -490,9 +560,10 @@ static void client_post_select(struct sched *s, struct task *t) out: t->error = ret; if (ret < 0) { - if (ret != -E_SERVER_EOF && ret != -E_BTR_EOF && ret != -E_EOF) + if (!ct->use_sideband && ret != -E_SERVER_EOF && + ret != -E_BTR_EOF && ret != -E_EOF) PARA_ERROR_LOG("%s\n", para_strerror(-t->error)); - btr_remove_node(btrn); + btr_remove_node(&ct->btrn); } }