diff --git a/include/proxysql_utils.h b/include/proxysql_utils.h index 2d75c4693..eb510357a 100644 --- a/include/proxysql_utils.h +++ b/include/proxysql_utils.h @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #ifndef ETIME // ETIME is not defined on FreeBSD @@ -205,4 +208,6 @@ std::string replace_str(const std::string& str, const std::string& match, const std::string generate_multi_rows_query(int rows, int params); + +void close_all_non_term_fd(std::vector excludeFDs); #endif diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index b5a0aca9b..5e46ffc16 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -189,23 +189,6 @@ static char * load_file (const char *filename) { */ -void close_all_non_term_fd() { - DIR *d; - struct dirent *dir; - d = opendir("/proc/self/fd"); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (strlen(dir->d_name) && dir->d_name[0] != '.') { - int fd = std::stol(std::string(dir->d_name)); - if (fd > 2) { - close(fd); - } - } - } - closedir(d); - } -} - static int round_intv_to_time_interval(int& intv) { if (intv > 300) { intv = 600; @@ -13620,7 +13603,7 @@ unsigned long long ProxySQL_External_Scheduler::run_once() { exit(EXIT_FAILURE); } if (cpid == 0) { - close_all_non_term_fd(); + close_all_non_term_fd({}); char *newenviron[] = { NULL }; int rc; rc=execve(sr->filename, newargs, newenviron); diff --git a/lib/proxysql_utils.cpp b/lib/proxysql_utils.cpp index 1207a04ef..27d8051be 100644 --- a/lib/proxysql_utils.cpp +++ b/lib/proxysql_utils.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -239,6 +240,9 @@ int wexecvp( // Duplicate file argument to avoid manual duplication _argv.insert(_argv.begin(), file.c_str()); + // close all files , with the exception of the pipes + close_all_non_term_fd({ CHILD_READ_FD, CHILD_WRITE_FD, CHILD_WRITE_ERR, PARENT_READ_FD, PARENT_READ_ERR, PARENT_WRITE_FD}); + // Copy the pipe descriptors int dup_read_err = dup2(CHILD_READ_FD, STDIN_FILENO); int dup_write_err = dup2(CHILD_WRITE_FD, STDOUT_FILENO); @@ -257,6 +261,7 @@ int wexecvp( close(PARENT_READ_ERR); close(PARENT_WRITE_FD); + char** args = const_cast(_argv.data()); child_err = execvp(file.c_str(), args); @@ -397,3 +402,32 @@ std::string generate_multi_rows_query(int rows, int params) { } return s; } + +void close_all_non_term_fd(std::vector excludeFDs) { + DIR *d; + struct dirent *dir; + d = opendir("/proc/self/fd"); + if (d) { + while ((dir = readdir(d)) != NULL) { + if (strlen(dir->d_name) && dir->d_name[0] != '.') { + int fd = std::stol(std::string(dir->d_name)); + if (fd > 2) { + if (std::find(excludeFDs.begin(), excludeFDs.end(), fd) == excludeFDs.end()) { + close(fd); + } + } + } + } + closedir(d); + } else { + struct rlimit nlimit; + int rc = getrlimit(RLIMIT_NOFILE, &nlimit); + if (rc == 0) { + for (unsigned int fd = 3; fd < nlimit.rlim_cur; fd++) { + if (std::find(excludeFDs.begin(), excludeFDs.end(), fd) == excludeFDs.end()) { + close(fd); + } + } + } + } +}