From d7a4e8faec7cb49013132adbaf598c0527070e5b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 7 Oct 2018 14:47:26 +0200 Subject: [PATCH] lib: Avoid the use of open_memstream in tevent_req_profile_string Solaris does not have it. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13629 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit e7d3678ddb5916416193d553f3cc562627e7d8ab) --- lib/tevent/test_req.c | 15 ++++++- lib/util/tevent_req_profile.c | 85 +++++++++++++++-------------------- lib/util/tevent_req_profile.h | 8 +--- 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/lib/tevent/test_req.c b/lib/tevent/test_req.c index 565ef31024f..2274a8cadc8 100644 --- a/lib/tevent/test_req.c +++ b/lib/tevent/test_req.c @@ -170,6 +170,7 @@ static bool test_tevent_req_profile2(struct torture_context *tctx, pid_t pid1, pid2; enum tevent_req_state state1, state2; uint64_t err1, err2; + char *printstring; ssize_t pack_len; int err; bool ok; @@ -189,7 +190,12 @@ static bool test_tevent_req_profile2(struct torture_context *tctx, TALLOC_FREE(req); TALLOC_FREE(ev); - tevent_req_profile_print(p1, stdout, 0, UINT_MAX); + printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX); + torture_assert_not_null( + tctx, + printstring, + "tevent_req_profile_string failed\n"); + printf("%s\n", printstring); pack_len = tevent_req_profile_pack(p1, NULL, 0); torture_assert(tctx, pack_len>0, "profile_pack failed\n"); @@ -212,7 +218,12 @@ static bool test_tevent_req_profile2(struct torture_context *tctx, "profile_unpack failed\n"); } - tevent_req_profile_print(p2, stdout, 0, UINT_MAX); + printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX); + torture_assert_not_null( + tctx, + printstring, + "tevent_req_profile_string failed\n"); + printf("%s\n", printstring); tevent_req_profile_get_name(p1, &str1); tevent_req_profile_get_name(p2, &str2); diff --git a/lib/util/tevent_req_profile.c b/lib/util/tevent_req_profile.c index 522741c5ede..2d280f78f32 100644 --- a/lib/util/tevent_req_profile.c +++ b/lib/util/tevent_req_profile.c @@ -29,10 +29,11 @@ #include "lib/util/time_basic.h" #include "lib/util/memory.h" -int tevent_req_profile_print(const struct tevent_req_profile *profile, - FILE *fp, - unsigned indent, - unsigned max_indent) +static bool tevent_req_profile_string_internal( + const struct tevent_req_profile *profile, + unsigned indent, + unsigned max_indent, + char **string) { struct timeval start, stop, diff; struct timeval_buf start_buf, stop_buf; @@ -44,7 +45,7 @@ int tevent_req_profile_print(const struct tevent_req_profile *profile, const char *state_buf = NULL; uint64_t user_error; const struct tevent_req_profile *sub = NULL; - int ret; + char *result; tevent_req_profile_get_name(profile, &req_name); @@ -85,8 +86,8 @@ int tevent_req_profile_print(const struct tevent_req_profile *profile, break; } - ret = fprintf( - fp, + result = talloc_asprintf_append_buffer( + *string, "%*s[%s] %s [%s] %s [%s] [%ju.%.6ju] -> %s (%d %"PRIu64"))\n", indent, "", @@ -100,72 +101,58 @@ int tevent_req_profile_print(const struct tevent_req_profile *profile, state_buf, (int)state, user_error); - - if (ret < 0) { - return ret; + if (result == NULL) { + return false; } + *string = result; indent += 1; if (indent >= max_indent) { - return ret; + return true; } for (sub = tevent_req_profile_get_subprofiles(profile); sub != NULL; sub = tevent_req_profile_next(sub)) { - int subret; - - subret = tevent_req_profile_print(sub, fp, indent, max_indent); - if (subret < 0) { - return subret; - } - - ret += subret; - - if (ret < subret) { - /* overflow */ - return -1; + bool ret; + + ret = tevent_req_profile_string_internal( + sub, + indent, + max_indent, + string); + if (!ret) { + return false; } } - return ret; + return true; } -char *tevent_req_profile_string(const struct tevent_req_profile *profile, - TALLOC_CTX *mem_ctx, +char *tevent_req_profile_string(TALLOC_CTX *mem_ctx, + const struct tevent_req_profile *profile, unsigned indent, unsigned max_indent) { - FILE *fp = NULL; - char *buf = NULL; - size_t buflen = 0; - char *result = NULL; - int ret; + char *result; + bool ret; - fp = open_memstream(&buf, &buflen); - if (fp == NULL) { + result = talloc_strdup(mem_ctx, ""); + if (result == NULL) { return NULL; } - ret = tevent_req_profile_print(profile, fp, 0, max_indent); - if (ret < 0) { - goto done; - } - - ret = fclose(fp); - if (ret != 0) { - goto done; + ret = tevent_req_profile_string_internal( + profile, + indent, + max_indent, + &result); + if (!ret) { + TALLOC_FREE(result); + return NULL; } - /* - * A FILE* from open_memstream maintains the 0-byte at the end - * beyond the reported length. - */ - result = talloc_memdup(mem_ctx, buf, buflen+1); - -done: - SAFE_FREE(buf); return result; } diff --git a/lib/util/tevent_req_profile.h b/lib/util/tevent_req_profile.h index 00dbc5a9cc2..3bcdbc1a289 100644 --- a/lib/util/tevent_req_profile.h +++ b/lib/util/tevent_req_profile.h @@ -29,12 +29,8 @@ #include "replace.h" #include -int tevent_req_profile_print(const struct tevent_req_profile *profile, - FILE *fp, - unsigned indent, - unsigned max_indent); -char *tevent_req_profile_string(const struct tevent_req_profile *profile, - TALLOC_CTX *mem_ctx, +char *tevent_req_profile_string(TALLOC_CTX *mem_ctx, + const struct tevent_req_profile *profile, unsigned indent, unsigned max_indent); ssize_t tevent_req_profile_pack( -- 2.19.0.605.g01d371f741-goog