lib: Avoid the use of open_memstream in tevent_req_profile_string
authorVolker Lendecke <vl@samba.org>
Sun, 7 Oct 2018 12:47:26 +0000 (14:47 +0200)
committerJeremy Allison <jra@samba.org>
Mon, 8 Oct 2018 20:17:11 +0000 (22:17 +0200)
Solaris does not have it.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13629
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
lib/tevent/test_req.c
lib/util/tevent_req_profile.c
lib/util/tevent_req_profile.h

index 565ef31024fb91e2a47affccce8457c50c748583..2274a8cadc8f0c93de1468107dfe6552a278d73b 100644 (file)
@@ -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);
index 522741c5ede8a8647bb053620a817bd3975f9555..2d280f78f322a76be07bfd2fe6ea5a386504859f 100644 (file)
 #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;
 }
 
index 00dbc5a9cc20869e121f80c303fe092303914465..3bcdbc1a28948c85fc081596a593e6a866cc4282 100644 (file)
 #include "replace.h"
 #include <tevent.h>
 
-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(