summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2024-10-23 19:48:31 -0500
committerJohn Estabrook <jestabro@vyos.io>2024-10-23 19:48:31 -0500
commit9d4787256f6b300927e7892047313d725787d828 (patch)
tree670a9875fdec008ff7f5089d5e930eaf04299ad4
parent3e16a23768680d95090e5c1d75a19395980e0a91 (diff)
downloadvyatta-cfg-9d4787256f6b300927e7892047313d725787d828.tar.gz
vyatta-cfg-9d4787256f6b300927e7892047313d725787d828.zip
T6717: add redirect_stdout
Legacy set/delete methods write errors to stdout; capture for redirection in return value.
-rw-r--r--src/vy_adapter.cpp104
-rw-r--r--src/vy_adapter.h4
2 files changed, 99 insertions, 9 deletions
diff --git a/src/vy_adapter.cpp b/src/vy_adapter.cpp
index 793728f..dd66dfb 100644
--- a/src/vy_adapter.cpp
+++ b/src/vy_adapter.cpp
@@ -21,12 +21,83 @@
#include <iostream>
#include <cstdint>
#include <cassert>
+#include <fcntl.h>
+#include <unistd.h>
#include <cstore/cstore.hpp>
#include <vy_adapter.h>
using namespace cstore;
+enum PIPES { READ, WRITE };
+
+extern FILE *out_stream;
+
+class stdout_redirect {
+ public:
+ stdout_redirect(): old_stdout(0), redirecting(false) {
+ out_pipe[READ] = 0;
+ out_pipe[WRITE] = 0;
+ if (pipe(out_pipe) == -1) {
+ return;
+ }
+
+ old_stdout = dup(fileno(stdout));
+ setbuf(stdout, NULL);
+ dup2(out_pipe[WRITE], fileno(stdout));
+
+ redirecting = true;
+ }
+
+ std::string get_redirected_output() {
+ if (!redirecting) {
+ return "";
+ }
+
+ char buffer[1024];
+ ssize_t bytesRead = 0;
+ std::string redirected_output = "\n";
+ fcntl(out_pipe[READ], F_SETFL, O_NONBLOCK);
+ while ((bytesRead = read(out_pipe[READ], buffer, sizeof(buffer))) > 0) {
+ redirected_output.append(buffer, bytesRead);
+ }
+
+ return redirected_output;
+ }
+
+ ~stdout_redirect() {
+ if (!redirecting) {
+ return;
+ }
+
+ dup2(old_stdout, fileno(stdout));
+
+ if (old_stdout > 0) {
+ close(old_stdout);
+ }
+ if (out_pipe[READ] > 0) {
+ close(out_pipe[READ]);
+ }
+ if (out_pipe[WRITE] > 0) {
+ close(out_pipe[WRITE]);
+ }
+ }
+
+ private:
+ int out_pipe[2];
+ int old_stdout;
+ bool redirecting;
+};
+
+const char *out_data_copy(std::string msg)
+{
+ size_t len = msg.length();
+ char *out_data = (char *) malloc(len + 1);
+ msg.copy(out_data, len);
+ out_data[len] = '\0';
+ return out_data;
+}
+
static uint64_t uint_of_voidptr(void* p)
{
assert (((uintptr_t) p & 1) == 0);
@@ -64,39 +135,58 @@ vy_in_session(uint64_t handle)
return h->inSession() ? 1 : 0;
}
-int
+const char *
vy_set_path(uint64_t handle, const void** path_ptr, size_t len)
{
Cstore *cstore = cstore_of_handle(handle);
const char **path = (const char **) path_ptr;
Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
int res;
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
res = cstore->validateSetPath(path_comps);
if (!res) {
- return 1;
+ out_str = "\nInvalid set path: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
+ goto out;
}
res = cstore->setCfgPath(path_comps);
if (!res) {
- return 2;
+ out_str = "\nSet config path failed: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
}
- return 0;
+out:
+ out_data = out_data_copy(out_str);
+ out_stream = NULL;
+ return out_data;
}
-int
+const char *
vy_delete_path(uint64_t handle, const void** path_ptr, size_t len)
{
Cstore *cstore = cstore_of_handle(handle);
const char **path = (const char **) path_ptr;
Cpath path_comps = Cpath(path, len);
+ const char *out_data;
+ std::string out_str = "";
int res;
+ out_stream = stdout;
+ stdout_redirect redirect = stdout_redirect();
+
res = cstore->deleteCfgPath(path_comps);
if (!res) {
- return 1;
+ out_str = "\nDelete failed: " + path_comps.to_string() + "\n";
+ out_str.append(redirect.get_redirected_output());
}
- return 0;
+ out_data = out_data_copy(out_str);
+ out_stream = NULL;
+ return out_data;
}
diff --git a/src/vy_adapter.h b/src/vy_adapter.h
index 8e0f376..fba6368 100644
--- a/src/vy_adapter.h
+++ b/src/vy_adapter.h
@@ -22,8 +22,8 @@ extern "C" {
uint64_t vy_cstore_init(void);
void vy_cstore_free(uint64_t);
int vy_in_session(uint64_t);
-int vy_set_path(uint64_t, const void **, size_t);
-int vy_delete_path(uint64_t, const void **, size_t);
+const char *vy_set_path(uint64_t, const void **, size_t);
+const char *vy_delete_path(uint64_t, const void **, size_t);
#ifdef __cplusplus
}