diff options
author | Amitay Isaacs <amitay@gmail.com> | 2018-07-11 18:35:46 +1000 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2019-03-26 07:49:18 +0000 |
commit | cd5f1904032e9fcb62ad8094addc841a6b9cb73a (patch) | |
tree | 64085415d944ece33d743beaf115f3ed49148fc0 | |
parent | 2c89c38851874637e1a7c92ce913427279b1cbe6 (diff) | |
download | samba-cd5f1904032e9fcb62ad8094addc841a6b9cb73a.tar.gz |
ctdb-protocol: Avoid fgets in ctdb_connection_list_read
C library buffering API can behave in unexpected fashion if underlying
fd for stdin, stdout or stderr is closed and re-opened.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13520
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
(cherry picked from commit c9b42d27e6cf9e6ae36f44970f0a388edc737a7a)
-rw-r--r-- | ctdb/protocol/protocol_util.c | 86 | ||||
-rw-r--r-- | ctdb/wscript | 4 |
2 files changed, 51 insertions, 39 deletions
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c index c75555fa734..45c639d747f 100644 --- a/ctdb/protocol/protocol_util.c +++ b/ctdb/protocol/protocol_util.c @@ -22,6 +22,8 @@ #include <talloc.h> +#include "common/line.h" + #include "protocol.h" #include "protocol_util.h" @@ -603,56 +605,66 @@ const char *ctdb_connection_list_to_string( return out; } -int ctdb_connection_list_read(TALLOC_CTX *mem_ctx, bool client_first, - struct ctdb_connection_list **conn_list) -{ +struct ctdb_connection_list_read_state { struct ctdb_connection_list *list; - char line[128]; /* long enough for IPv6 */ + bool client_first; +}; + +static int ctdb_connection_list_read_line(char *line, void *private_data) +{ + struct ctdb_connection_list_read_state *state = + (struct ctdb_connection_list_read_state *)private_data; + struct ctdb_connection conn; int ret; - if (conn_list == NULL) { - return EINVAL; + /* Skip empty lines */ + if (line[0] == '\0') { + return 0; } - list = talloc_zero(mem_ctx, struct ctdb_connection_list); - if (list == NULL) { - return ENOMEM; + /* Comment */ + if (line[0] == '#') { + return 0; } - while (fgets(line, sizeof(line), stdin) != NULL) { - char *t; - struct ctdb_connection conn; + ret = ctdb_connection_from_string(line, state->client_first, &conn); + if (ret != 0) { + return ret; + } - /* Skip empty lines */ - if (line[0] == '\n') { - continue; - } + ret = ctdb_connection_list_add(state->list, &conn); + if (ret != 0) { + return ret; + } - /* Comment */ - if (line[0] == '#') { - continue; - } + return 0; +} - t = strtok(line, "\n"); - if (t == NULL) { - goto fail; - } +int ctdb_connection_list_read(TALLOC_CTX *mem_ctx, bool client_first, + struct ctdb_connection_list **conn_list) +{ + struct ctdb_connection_list_read_state state; + int ret; - ret = ctdb_connection_from_string(t, client_first, &conn); - if (ret != 0) { - goto fail; - } + if (conn_list == NULL) { + return EINVAL; + } - ret = ctdb_connection_list_add(list, &conn); - if (ret != 0) { - goto fail; - } + state.list = talloc_zero(mem_ctx, struct ctdb_connection_list); + if (state.list == NULL) { + return ENOMEM; } - *conn_list = list; - return 0; + state.client_first = client_first; + + ret = line_read(0, + 128, + mem_ctx, + ctdb_connection_list_read_line, + &state, + NULL); -fail: - talloc_free(list); - return EINVAL; + *conn_list = state.list; + + return ret; } diff --git a/ctdb/wscript b/ctdb/wscript index e3bcdf7e962..8727fd8aefa 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -433,7 +433,7 @@ def build(bld): bld.SAMBA_SUBSYSTEM('ctdb-protocol-util', source='protocol/protocol_util.c', - deps='replace talloc tdb') + deps='ctdb-util replace talloc tdb') bld.SAMBA_SUBSYSTEM('ctdb-client', source=bld.SUBDIR('client', 'ctdb_client.c'), @@ -824,7 +824,7 @@ def build(bld): bld.SAMBA_BINARY(target, source=src, deps='''protocol-tests-common - samba-util talloc tdb''', + samba-util ctdb-util talloc tdb''', install_path='${CTDB_TEST_LIBEXECDIR}') bld.SAMBA_SUBSYSTEM('ctdb-tests-common', |