mirror of
https://github.com/google/nsjail.git
synced 2026-08-30 18:41:30 -07:00
Apply nodiscard to critical core bounds validation and setup primitives
This commit is contained in:
10
caps.cc
10
caps.cc
@@ -106,7 +106,7 @@ static std::string capToStr(int val) {
|
||||
return util::StrPrintf("CAP_UNKNOWN(%d)", val);
|
||||
}
|
||||
|
||||
static bool getCaps(cap_user_data_t cap_data) {
|
||||
[[nodiscard]] static bool getCaps(cap_user_data_t cap_data) {
|
||||
const struct __user_cap_header_struct cap_hdr = {
|
||||
.version = _LINUX_CAPABILITY_VERSION_3,
|
||||
.pid = 0,
|
||||
@@ -118,7 +118,7 @@ static bool getCaps(cap_user_data_t cap_data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setCaps(const cap_user_data_t cap_data) {
|
||||
[[nodiscard]] static bool setCaps(const cap_user_data_t cap_data) {
|
||||
const struct __user_cap_header_struct cap_hdr = {
|
||||
.version = _LINUX_CAPABILITY_VERSION_3,
|
||||
.pid = 0,
|
||||
@@ -136,19 +136,19 @@ static void clearInheritable(cap_user_data_t cap_data) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool getPermitted(cap_user_data_t cap_data, unsigned int cap) {
|
||||
[[nodiscard]] static bool getPermitted(cap_user_data_t cap_data, unsigned int cap) {
|
||||
size_t off_byte = CAP_TO_INDEX(cap);
|
||||
unsigned mask = CAP_TO_MASK(cap);
|
||||
return cap_data[off_byte].permitted & mask;
|
||||
}
|
||||
|
||||
static bool getEffective(cap_user_data_t cap_data, unsigned int cap) {
|
||||
[[nodiscard]] static bool getEffective(cap_user_data_t cap_data, unsigned int cap) {
|
||||
size_t off_byte = CAP_TO_INDEX(cap);
|
||||
unsigned mask = CAP_TO_MASK(cap);
|
||||
return cap_data[off_byte].effective & mask;
|
||||
}
|
||||
|
||||
static bool getInheritable(cap_user_data_t cap_data, unsigned int cap) {
|
||||
[[nodiscard]] static bool getInheritable(cap_user_data_t cap_data, unsigned int cap) {
|
||||
size_t off_byte = CAP_TO_INDEX(cap);
|
||||
unsigned mask = CAP_TO_MASK(cap);
|
||||
return cap_data[off_byte].inheritable & mask;
|
||||
|
||||
@@ -131,7 +131,7 @@ struct ThreadCtx {
|
||||
|
||||
static thread_local ThreadCtx current_ctx;
|
||||
|
||||
bool addFd(int fd, uint32_t events, fdCb_t cb, void* data) {
|
||||
[[nodiscard]] bool addFd(int fd, uint32_t events, fdCb_t cb, void* data) {
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ constexpr uint32_t MSG_TAG_ERROR = quad('E', 'R', 'R', 'F');
|
||||
typedef void (*fdCb_t)(int fd, uint32_t events, void* data);
|
||||
typedef void (*periodicCb_t)();
|
||||
|
||||
bool addFd(int fd, uint32_t events, fdCb_t cb, void* data);
|
||||
[[nodiscard]] bool addFd(int fd, uint32_t events, fdCb_t cb, void* data);
|
||||
bool removeFd(int fd);
|
||||
bool modFd(int fd, uint32_t events);
|
||||
void addPeriodic(periodicCb_t cb);
|
||||
|
||||
4
net.cc
4
net.cc
@@ -353,7 +353,7 @@ static void pastaProcess(nsj_t* nsj, int pid, int err_pipe) {
|
||||
pasta_path = argv[0];
|
||||
}
|
||||
|
||||
util::makeRangeCOE(STDERR_FILENO + 1, ~0U);
|
||||
(void)util::makeRangeCOE(STDERR_FILENO + 1, ~0U);
|
||||
|
||||
/* LOG doesn't use STDERR_FILENO so it's fine to use it */
|
||||
int err = 0;
|
||||
@@ -369,7 +369,7 @@ static void pastaProcess(nsj_t* nsj, int pid, int err_pipe) {
|
||||
PLOG_W("execvpe('%s')", pasta_path);
|
||||
}
|
||||
|
||||
util::writeToFd(err_pipe, &err, sizeof(err));
|
||||
(void)util::writeToFd(err_pipe, &err, sizeof(err));
|
||||
}
|
||||
|
||||
static bool spawnPasta(nsj_t* nsj, int pid) {
|
||||
|
||||
@@ -539,7 +539,7 @@ static void handle_host_udp_control(Context* ctx, UdpFlow* flow, uint32_t events
|
||||
kUdpStateTable[state_idx].on_host_control(ctx, flow, events);
|
||||
}
|
||||
|
||||
static bool udp_setup_socks5_control(
|
||||
[[nodiscard]] static bool udp_setup_socks5_control(
|
||||
Context* ctx, UdpFlow* flow, uint32_t proxy_ip4, uint16_t proxy_port) {
|
||||
int tcp_fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||
if (tcp_fd == -1) {
|
||||
@@ -580,7 +580,7 @@ static bool udp_setup_socks5_control(
|
||||
return true;
|
||||
}
|
||||
|
||||
static int create_and_bind_udp_socket(Context* ctx) {
|
||||
[[nodiscard]] static int create_and_bind_udp_socket(Context* ctx) {
|
||||
int fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||
if (fd == -1) {
|
||||
PLOG_E("socket(AF_INET, SOCK_DGRAM) for UDP flow failed");
|
||||
|
||||
@@ -89,7 +89,7 @@ bool installUnotifyFilter(nsj_t* nsj, int ipc_fd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool prepareAndCommit(nsj_t* nsj) {
|
||||
[[nodiscard]] static bool prepareAndCommit(nsj_t* nsj) {
|
||||
if (nsj->seccomp_fprog.len == 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ static bool prepareAndCommit(nsj_t* nsj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool applyPolicy(nsj_t* nsj, int ipc_fd) {
|
||||
[[nodiscard]] bool applyPolicy(nsj_t* nsj, int ipc_fd) {
|
||||
if (ipc_fd != -1 && nsj->njc.seccomp_unotify()) {
|
||||
if (!installUnotifyFilter(nsj, ipc_fd)) {
|
||||
return false;
|
||||
@@ -123,7 +123,7 @@ bool applyPolicy(nsj_t* nsj, int ipc_fd) {
|
||||
return prepareAndCommit(nsj);
|
||||
}
|
||||
|
||||
bool preparePolicy(nsj_t* nsj) {
|
||||
[[nodiscard]] bool preparePolicy(nsj_t* nsj) {
|
||||
nsj->seccomp_fprog.len = 0;
|
||||
nsj->seccomp_fprog.filter = nullptr;
|
||||
nsj->seccomp_unotify_fprog.len = 0;
|
||||
|
||||
14
subproc.cc
14
subproc.cc
@@ -117,7 +117,7 @@ static std::string cloneFlagsToStr(uint64_t flags) {
|
||||
}
|
||||
|
||||
/* Reset the execution environment for the new process */
|
||||
static bool resetEnv(void) {
|
||||
[[nodiscard]] static bool resetEnv(void) {
|
||||
/* Set all previously changed signals to their default behavior */
|
||||
for (const auto& sig : nssigs) {
|
||||
if (signal(sig, SIG_DFL) == SIG_ERR) {
|
||||
@@ -452,7 +452,7 @@ void killAll(nsj_t* nsj, int signal) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool initParent(nsj_t* nsj, pid_t pid, int ipc_fd) {
|
||||
[[nodiscard]] static bool initParent(nsj_t* nsj, pid_t pid, int ipc_fd) {
|
||||
if (!net::initParent(nsj, pid, ipc_fd)) {
|
||||
LOG_W("Couldn't initialize net namespace for pid=%d", pid);
|
||||
return false;
|
||||
@@ -524,7 +524,7 @@ pid_t runChild(
|
||||
close(parent_fd);
|
||||
|
||||
newProc(nsj, netfd, fd_in, fd_out, fd_err, child_fd);
|
||||
util::sendMsg(child_fd, monitor::MSG_TAG_ERROR);
|
||||
(void)util::sendMsg(child_fd, monitor::MSG_TAG_ERROR);
|
||||
LOG_E("Launching child process failed");
|
||||
pause();
|
||||
_exit(0xff);
|
||||
@@ -563,7 +563,7 @@ pid_t runChild(
|
||||
* Returns child pid in the parent, 0 in the child, -1 on error.
|
||||
* On success, *pidfd receives a file descriptor referring to the child.
|
||||
*/
|
||||
pid_t cloneProc(uint64_t flags, int exit_signal, int* pidfd) {
|
||||
[[nodiscard]] pid_t cloneProc(uint64_t flags, int exit_signal, int* pidfd) {
|
||||
exit_signal &= CSIGNAL;
|
||||
|
||||
if (flags & CLONE_VM) {
|
||||
@@ -594,7 +594,7 @@ pid_t cloneProc(uint64_t flags, int exit_signal, int* pidfd) {
|
||||
* Lightweight clone3 wrapper for internal helpers (mnt, pid) that need
|
||||
* specific flags (e.g. CLONE_FS) but no pidfd tracking.
|
||||
*/
|
||||
pid_t cloneProcNoPidfd(uint64_t flags, int exit_signal) {
|
||||
[[nodiscard]] pid_t cloneProcNoPidfd(uint64_t flags, int exit_signal) {
|
||||
exit_signal &= CSIGNAL;
|
||||
|
||||
struct clone_args ca = {};
|
||||
@@ -608,7 +608,7 @@ pid_t cloneProcNoPidfd(uint64_t flags, int exit_signal) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int systemExe(const std::vector<std::string>& args, char** env) {
|
||||
[[nodiscard]] int systemExe(const std::vector<std::string>& args, char** env) {
|
||||
bool exec_failed = false;
|
||||
|
||||
std::vector<const char*> argv;
|
||||
@@ -634,7 +634,7 @@ int systemExe(const std::vector<std::string>& args, char** env) {
|
||||
close(sv[0]);
|
||||
execve(argv[0], (char* const*)argv.data(), (char* const*)env);
|
||||
PLOG_W("execve('%s')", argv[0]);
|
||||
util::writeToFd(sv[1], "A", 1);
|
||||
(void)util::writeToFd(sv[1], "A", 1);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@ int reapAll(nsj_t* nsj);
|
||||
int reapProc(nsj_t* nsj, pid_t pid, bool should_wait = false);
|
||||
uint64_t checkTimeouts(
|
||||
nsj_t* nsj, pid_t target_pid, time_t start_time, const std::string& remote_txt, int pidfd);
|
||||
int systemExe(const std::vector<std::string>& args, char** env);
|
||||
pid_t cloneProc(uint64_t flags, int exit_signal, int* pidfd);
|
||||
[[nodiscard]] int systemExe(const std::vector<std::string>& args, char** env);
|
||||
[[nodiscard]] pid_t cloneProc(uint64_t flags, int exit_signal, int* pidfd);
|
||||
|
||||
pid_t cloneProcNoPidfd(uint64_t flags, int exit_signal);
|
||||
[[nodiscard]] pid_t cloneProcNoPidfd(uint64_t flags, int exit_signal);
|
||||
|
||||
} // namespace subproc
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ static void unotifyCb(int fd, uint32_t events, void* /* data */) {
|
||||
* Returns true if the fd was successfully absorbed by the loop. On failure,
|
||||
* the fd is untouched and remains the caller's responsibility to close.
|
||||
*/
|
||||
bool start(nsj_t* nsj, int fd, int pidfd) {
|
||||
[[nodiscard]] bool start(nsj_t* nsj, int fd, int pidfd) {
|
||||
if (current_ctx.fd != -1) {
|
||||
LOG_W("unotify::start called on already initialized context");
|
||||
return false;
|
||||
|
||||
18
user.cc
18
user.cc
@@ -61,7 +61,7 @@ constexpr char kNewGidPath[] =
|
||||
|
||||
namespace user {
|
||||
|
||||
static bool setResGid(gid_t gid) {
|
||||
[[nodiscard]] static bool setResGid(gid_t gid) {
|
||||
LOG_D("setresgid(%d)", gid);
|
||||
#if defined(__NR_setresgid32)
|
||||
if (util::syscall(__NR_setresgid32, (uintptr_t)gid, (uintptr_t)gid, (uintptr_t)gid) == -1) {
|
||||
@@ -77,7 +77,7 @@ static bool setResGid(gid_t gid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool setResUid(uid_t uid) {
|
||||
[[nodiscard]] static bool setResUid(uid_t uid) {
|
||||
LOG_D("setresuid(%d)", uid);
|
||||
#if defined(__NR_setresuid32)
|
||||
if (util::syscall(__NR_setresuid32, (uintptr_t)uid, (uintptr_t)uid, (uintptr_t)uid) == -1) {
|
||||
@@ -93,7 +93,7 @@ static bool setResUid(uid_t uid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool hasGidMapSelf(nsj_t* nsj) {
|
||||
[[nodiscard]] static bool hasGidMapSelf(nsj_t* nsj) {
|
||||
for (const auto& gid : nsj->gids) {
|
||||
if (!gid.is_newidmap) {
|
||||
return true;
|
||||
@@ -102,7 +102,7 @@ static bool hasGidMapSelf(nsj_t* nsj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool setGroupsDeny(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool setGroupsDeny(nsj_t* nsj, pid_t pid) {
|
||||
/*
|
||||
* No need to write 'deny' to /proc/pid/setgroups if our euid==0, as writing to
|
||||
* uid_map/gid_map will succeed anyway
|
||||
@@ -120,7 +120,7 @@ static bool setGroupsDeny(nsj_t* nsj, pid_t pid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool uidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
std::string map;
|
||||
for (const auto& uid : nsj->uids) {
|
||||
if (uid.is_newidmap) {
|
||||
@@ -147,7 +147,7 @@ static bool uidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool gidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
std::string map;
|
||||
for (const auto& gid : nsj->gids) {
|
||||
if (gid.is_newidmap) {
|
||||
@@ -175,7 +175,7 @@ static bool gidMapSelf(nsj_t* nsj, pid_t pid) {
|
||||
}
|
||||
|
||||
/* Use newgidmap for writing the gid map */
|
||||
static bool gidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool gidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
bool use = false;
|
||||
|
||||
std::vector<std::string> argv = {kNewGidPath, std::to_string(pid)};
|
||||
@@ -201,7 +201,7 @@ static bool gidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
}
|
||||
|
||||
/* Use newuidmap for writing the uid map */
|
||||
static bool uidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool uidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
bool use = false;
|
||||
|
||||
std::vector<std::string> argv = {kNewUidPath, std::to_string(pid)};
|
||||
@@ -226,7 +226,7 @@ static bool uidMapExternal(nsj_t* nsj, pid_t pid) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool uidGidMap(nsj_t* nsj, pid_t pid) {
|
||||
[[nodiscard]] static bool uidGidMap(nsj_t* nsj, pid_t pid) {
|
||||
RETURN_ON_FAILURE(gidMapSelf(nsj, pid));
|
||||
RETURN_ON_FAILURE(gidMapExternal(nsj, pid));
|
||||
RETURN_ON_FAILURE(uidMapSelf(nsj, pid));
|
||||
|
||||
2
user.h
2
user.h
@@ -32,7 +32,7 @@ namespace user {
|
||||
|
||||
bool initNsFromParent(nsj_t* nsj, pid_t pid);
|
||||
bool initNs(nsj_t* nsj);
|
||||
bool parseId(nsj_t* nsj, const std::string& i_id, const std::string& o_id, size_t cnt, bool is_gid,
|
||||
[[nodiscard]] bool parseId(nsj_t* nsj, const std::string& i_id, const std::string& o_id, size_t cnt, bool is_gid,
|
||||
bool is_newidmap);
|
||||
|
||||
} // namespace user
|
||||
|
||||
20
util.cc
20
util.cc
@@ -53,7 +53,7 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
ssize_t readFromFd(int fd, void* buf, size_t len) {
|
||||
[[nodiscard]] ssize_t readFromFd(int fd, void* buf, size_t len) {
|
||||
uint8_t* charbuf = (uint8_t*)buf;
|
||||
|
||||
size_t readSz = 0;
|
||||
@@ -70,7 +70,7 @@ ssize_t readFromFd(int fd, void* buf, size_t len) {
|
||||
return readSz;
|
||||
}
|
||||
|
||||
ssize_t readFromFile(const char* fname, void* buf, size_t len) {
|
||||
[[nodiscard]] ssize_t readFromFile(const char* fname, void* buf, size_t len) {
|
||||
int fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
|
||||
if (fd == -1) {
|
||||
LOG_E("open(%s, O_RDONLY|O_CLOEXEC)", QC(fname));
|
||||
@@ -81,7 +81,7 @@ ssize_t readFromFile(const char* fname, void* buf, size_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool writeToFd(int fd, const void* buf, size_t len) {
|
||||
[[nodiscard]] bool writeToFd(int fd, const void* buf, size_t len) {
|
||||
const uint8_t* charbuf = (const uint8_t*)buf;
|
||||
|
||||
size_t writtenSz = 0;
|
||||
@@ -95,7 +95,7 @@ bool writeToFd(int fd, const void* buf, size_t len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sendMsg(int sock, uint32_t msg_val, int fd) {
|
||||
[[nodiscard]] bool sendMsg(int sock, uint32_t msg_val, int fd) {
|
||||
struct msghdr msg = {};
|
||||
struct iovec io = {
|
||||
.iov_base = &msg_val,
|
||||
@@ -122,7 +122,7 @@ bool sendMsg(int sock, uint32_t msg_val, int fd) {
|
||||
return (TEMP_FAILURE_RETRY(sendmsg(sock, &msg, 0)) == sizeof(msg_val));
|
||||
}
|
||||
|
||||
bool recvMsg(int sock, uint32_t* msg_val, int* fd) {
|
||||
[[nodiscard]] bool recvMsg(int sock, uint32_t* msg_val, int* fd) {
|
||||
struct msghdr msg = {};
|
||||
uint32_t local_msg = 0;
|
||||
struct iovec io = {
|
||||
@@ -165,7 +165,7 @@ bool recvMsg(int sock, uint32_t* msg_val, int* fd) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readFromFileToStr(const char* fname, std::string* str) {
|
||||
[[nodiscard]] bool readFromFileToStr(const char* fname, std::string* str) {
|
||||
int fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC));
|
||||
if (fd == -1) {
|
||||
PLOG_W("Couldn't open file %s", QC(fname));
|
||||
@@ -191,7 +191,7 @@ bool readFromFileToStr(const char* fname, std::string* str) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeBufToFile(
|
||||
[[nodiscard]] bool writeBufToFile(
|
||||
const char* filename, const void* buf, size_t len, int open_flags, bool log_errors) {
|
||||
int fd;
|
||||
TEMP_FAILURE_RETRY(fd = open(filename, open_flags | O_CLOEXEC, 0644));
|
||||
@@ -220,7 +220,7 @@ bool writeBufToFile(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool createDirRecursively(const char* dir) {
|
||||
[[nodiscard]] bool createDirRecursively(const char* dir) {
|
||||
if (dir[0] != '/') {
|
||||
LOG_W("The directory path must start with '/': '%s' provided", dir);
|
||||
return false;
|
||||
@@ -499,7 +499,7 @@ long getrlimit(int res, struct rlimit64* curlim) {
|
||||
return util::syscall(__NR_prlimit64, 0, res, (uintptr_t)nullptr, (uintptr_t)curlim);
|
||||
}
|
||||
|
||||
bool makeRangeCOE(unsigned int first, unsigned int last) {
|
||||
[[nodiscard]] bool makeRangeCOE(unsigned int first, unsigned int last) {
|
||||
if (util::syscall(__NR_close_range, first, last, CLOSE_RANGE_CLOEXEC) == -1) {
|
||||
if (errno != ENOSYS) {
|
||||
PLOG_E("close_range(first=%u, last=%u, CLOSE_RANGE_CLOEXEC)", first, last);
|
||||
@@ -554,7 +554,7 @@ void detachFromTTY(void) {
|
||||
LOG_D("Successfully detached from controlling terminal via TIOCNOTTY");
|
||||
}
|
||||
|
||||
bool setNonBlock(int fd) {
|
||||
[[nodiscard]] bool setNonBlock(int fd) {
|
||||
int fl = fcntl(fd, F_GETFL, 0);
|
||||
if (fl == -1 || fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1) {
|
||||
PLOG_W("fcntl(fd=%d, O_NONBLOCK)", fd);
|
||||
|
||||
20
util.h
20
util.h
@@ -47,16 +47,16 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
ssize_t readFromFd(int fd, void* buf, size_t len);
|
||||
ssize_t readFromFile(const char* fname, void* buf, size_t len);
|
||||
bool readFromFileToStr(const char* fname, std::string* str);
|
||||
bool writeToFd(int fd, const void* buf, size_t len);
|
||||
[[nodiscard]] ssize_t readFromFd(int fd, void* buf, size_t len);
|
||||
[[nodiscard]] ssize_t readFromFile(const char* fname, void* buf, size_t len);
|
||||
[[nodiscard]] bool readFromFileToStr(const char* fname, std::string* str);
|
||||
[[nodiscard]] bool writeToFd(int fd, const void* buf, size_t len);
|
||||
|
||||
bool sendMsg(int sock, uint32_t msg, int fd = -1);
|
||||
bool recvMsg(int sock, uint32_t* msg, int* fd = nullptr);
|
||||
bool writeBufToFile(
|
||||
[[nodiscard]] bool sendMsg(int sock, uint32_t msg, int fd = -1);
|
||||
[[nodiscard]] bool recvMsg(int sock, uint32_t* msg, int* fd = nullptr);
|
||||
[[nodiscard]] bool writeBufToFile(
|
||||
const char* filename, const void* buf, size_t len, int open_flags, bool log_errors = true);
|
||||
bool createDirRecursively(const char* dir);
|
||||
[[nodiscard]] bool createDirRecursively(const char* dir);
|
||||
std::string* StrAppend(std::string* str, const char* format, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
std::string StrPrintf(const char* format, ...) __attribute__((format(printf, 1, 2)));
|
||||
@@ -73,11 +73,11 @@ long syscall(long sysno, uintptr_t a0 = 0, uintptr_t a1 = 0, uintptr_t a2 = 0, u
|
||||
uintptr_t a4 = 0, uintptr_t a5 = 0);
|
||||
long setrlimit(int res, const struct rlimit64& newlim);
|
||||
long getrlimit(int res, struct rlimit64* curlim);
|
||||
bool makeRangeCOE(unsigned int first, unsigned int last);
|
||||
[[nodiscard]] bool makeRangeCOE(unsigned int first, unsigned int last);
|
||||
const char* stripLeadingSlashes(const char* path);
|
||||
bool kernelVersionAtLeast(int major, int minor, int patch);
|
||||
void detachFromTTY(void);
|
||||
bool setNonBlock(int fd);
|
||||
[[nodiscard]] bool setNonBlock(int fd);
|
||||
bool setNoDelay(int fd);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user