From 4162ae05cad637fc110e53ce40375fdf30900aa7 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 4 Sep 2017 16:12:55 +0800 Subject: [PATCH] test/coredumpctl: support freebsd setrlimit() on platforms without prctl() Signed-off-by: Kefu Chai --- src/include/coredumpctl.h | 72 +++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 7 deletions(-) diff --git a/src/include/coredumpctl.h b/src/include/coredumpctl.h index 9b0f160e0a397..60fab43236744 100644 --- a/src/include/coredumpctl.h +++ b/src/include/coredumpctl.h @@ -1,13 +1,24 @@ #pragma once +#include "acconfig.h" + #ifdef HAVE_SYS_PRCTL_H #include #include #include "common/errno.h" -struct PrCtl { +class PrCtl { int saved_state = -1; - int set_dumpable(int new_state) { + static int get_dumpable() { + int r = prctl(PR_GET_DUMPABLE); + if (r == -1) { + r = errno; + std::cerr << "warning: unable to get dumpable flag: " << cpp_strerror(r) + << std::endl; + } + return r; + } + static int set_dumpable(bool new_state) { int r = prctl(PR_SET_DUMPABLE, new_state); if (r) { r = -errno; @@ -17,13 +28,13 @@ struct PrCtl { } return r; } +public: PrCtl(int new_state = 0) { - int r = prctl(PR_GET_DUMPABLE); + int r = get_dumpable(); if (r == -1) { - r = errno; - std::cerr << "warning: unable to get dumpable flag: " << cpp_strerror(r) - << std::endl; - } else if (r != new_state) { + return; + } + if (r != new_state) { if (!set_dumpable(new_state)) { saved_state = r; } @@ -38,10 +49,57 @@ struct PrCtl { }; #else +#include +#ifdef RLIMIT_CORE +#include +#include +#include "common/errno.h" +class PrCtl { + rlimit saved_lim; + static int get_dumpable(rlimit* saved) { + int r = getrlimit(RLIMIT_CORE, saved); + if (r) { + r = errno; + std::cerr << "warning: unable to getrlimit(): " << cpp_strerror(r) + << std::endl; + } + return r; + } + static void set_dumpable(const rlimit& rlim) { + int r = setrlimit(RLIMIT_CORE, &rlim); + if (r) { + r = -errno; + std::cerr << "warning: unable to setrlimit(): " << cpp_strerror(r) + << std::endl; + } + } +public: + PrCtl(int new_state = 0) { + int r = get_dumpable(&saved_lim); + if (r == -1) { + return; + } + rlimit new_lim; + if (new_state) { + new_lim.rlim_cur = saved_lim.rlim_max; + } else { + new_lim.rlim_cur = new_lim.rlim_max = 0; + } + if (new_lim.rlim_cur == saved_lim.rlim_cur) { + return; + } + set_dumpable(new_lim); + } + ~PrCtl() { + set_dumpable(saved_lim); + } +}; +#else struct PrCtl { // to silence the Wunused-variable warning PrCtl() {} }; +#endif // RLIMIT_CORE #endif -- 2.39.5