From 28ba006ce571be31ce64eb5e0ef26900d17eb3c9 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 29 Aug 2024 15:14:46 +0200 Subject: [PATCH] cleanup(userspace/libscap): avoid the usage of non-portable (glibc specific) `__gnu_cxx::stdio_filebuf`. Signed-off-by: Federico Di Pierro --- userspace/libscap/engine/gvisor/runsc.cpp | 55 +++++++++++------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/userspace/libscap/engine/gvisor/runsc.cpp b/userspace/libscap/engine/gvisor/runsc.cpp index bdedd4e245..e537116988 100644 --- a/userspace/libscap/engine/gvisor/runsc.cpp +++ b/userspace/libscap/engine/gvisor/runsc.cpp @@ -16,10 +16,6 @@ limitations under the License. */ #include -#include -#include -#include -#include #include #include @@ -30,36 +26,37 @@ namespace runsc { result runsc(char *argv[]) { result res; - int pipefds[2]; - int ret = pipe(pipefds); - if(ret) { - return res; + std::string full_command; + int i = 0; + while(true) { + if(argv[i] == nullptr) { + break; + } + full_command.append(argv[i]); + full_command.append(" "); + i++; } - - pid_t pid = vfork(); - if(pid > 0) { - int status; - - close(pipefds[1]); - wait(&status); + FILE *cmd_out = popen(full_command.c_str(), "r"); + if(cmd_out == nullptr) { + res.error = -errno; + } else { + char *out = nullptr; + size_t len = 0; + ssize_t readbytes; + while((readbytes = getline(&out, &len, cmd_out)) >= 0) { + // getline() returns string comprehensive of newline char; + // drop it if found. + if(out[readbytes - 1] == '\n') { + out[readbytes - 1] = '\0'; + } + res.output.emplace_back(out); + } + free(out); + int status = pclose(cmd_out); if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) { res.error = status; - return res; } - - __gnu_cxx::stdio_filebuf filebuf(pipefds[0], std::ios::in); - std::string line; - std::istream is(&filebuf); - - while(std::getline(is, line)) { - res.output.emplace_back(std::string(line)); - } - } else { - close(pipefds[0]); - dup2(pipefds[1], STDOUT_FILENO); - execvp("runsc", argv); - exit(1); } return res;