mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-14 09:05:59 +01:00
07e070012b
* CrashReporter: skip Linux field on BSDs after90a53aed59
In file included from src/debug/CrashReporter.cpp:10: src/debug/signal-safe.hpp:113:17: error: no member named 'sa_restorer' in 'sigaction' act.sa_restorer = NULL; ~~~ ^ * CrashReporter: ensure *argv[] is NULL-terminated after90a53aed59
execv() may fail with EFAULT otherwise. * hyprpm: add missing header after335015fe2d
hyprpm/src/core/PluginManager.cpp:165:43: error: use of undeclared identifier 'getuid' 165 | const std::string USERNAME = getpwuid(getuid())->pw_name; | ^ hyprpm/src/core/PluginManager.cpp:431:45: error: use of undeclared identifier 'getuid' 431 | const std::string USERNAME = getpwuid(getuid())->pw_name; | ^ hyprpm/src/core/PluginManager.cpp:558:43: error: use of undeclared identifier 'getuid' 558 | const std::string USERNAME = getpwuid(getuid())->pw_name; | ^
174 lines
4.5 KiB
C++
174 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#include "defines.hpp"
|
|
|
|
template <uint16_t N>
|
|
class MaxLengthCString {
|
|
public:
|
|
MaxLengthCString() : m_strPos(0), m_boundsExceeded(false) {
|
|
m_str[0] = '\0';
|
|
}
|
|
inline void operator+=(char const* rhs) {
|
|
write(rhs, strlen(rhs));
|
|
}
|
|
void write(char const* data, size_t len) {
|
|
if (m_boundsExceeded || m_strPos + len >= N) {
|
|
m_boundsExceeded = true;
|
|
return;
|
|
}
|
|
memcpy(m_str + m_strPos, data, len);
|
|
m_strPos += len;
|
|
m_str[m_strPos] = '\0';
|
|
}
|
|
void write(char c) {
|
|
if (m_boundsExceeded || m_strPos + 1 >= N) {
|
|
m_boundsExceeded = true;
|
|
return;
|
|
}
|
|
m_str[m_strPos] = c;
|
|
m_strPos++;
|
|
}
|
|
void write_num(size_t num) {
|
|
size_t d = 1;
|
|
while (num / 10 >= d)
|
|
d *= 10;
|
|
while (num > 0) {
|
|
char c = '0' + (num / d);
|
|
write(c);
|
|
num %= d;
|
|
d /= 10;
|
|
}
|
|
}
|
|
char const* get_str() {
|
|
return m_str;
|
|
};
|
|
bool boundsExceeded() {
|
|
return m_boundsExceeded;
|
|
};
|
|
|
|
private:
|
|
char m_str[N];
|
|
size_t m_strPos;
|
|
bool m_boundsExceeded;
|
|
};
|
|
|
|
template <uint16_t BUFSIZE>
|
|
class BufFileWriter {
|
|
public:
|
|
inline BufFileWriter(int fd_) : m_writeBufPos(0), m_fd(fd_) {}
|
|
~BufFileWriter() {
|
|
flush();
|
|
}
|
|
void write(char const* data, size_t len) {
|
|
while (len > 0) {
|
|
size_t to_add = std::min(len, (size_t)BUFSIZE - m_writeBufPos);
|
|
memcpy(m_writeBuf + m_writeBufPos, data, to_add);
|
|
data += to_add;
|
|
len -= to_add;
|
|
m_writeBufPos += to_add;
|
|
if (m_writeBufPos == BUFSIZE)
|
|
flush();
|
|
}
|
|
}
|
|
inline void write(char c) {
|
|
if (m_writeBufPos == BUFSIZE)
|
|
flush();
|
|
m_writeBuf[m_writeBufPos] = c;
|
|
m_writeBufPos++;
|
|
}
|
|
inline void operator+=(char const* str) {
|
|
write(str, strlen(str));
|
|
}
|
|
inline void operator+=(std::string_view str) {
|
|
write(str.data(), str.size());
|
|
}
|
|
inline void operator+=(char c) {
|
|
write(c);
|
|
}
|
|
void writeNum(size_t num) {
|
|
size_t d = 1;
|
|
while (num / 10 >= d)
|
|
d *= 10;
|
|
while (num > 0) {
|
|
char c = '0' + (num / d);
|
|
write(c);
|
|
num %= d;
|
|
d /= 10;
|
|
}
|
|
}
|
|
void writeCmdOutput(const char* cmd) {
|
|
int pipefd[2];
|
|
if (pipe(pipefd) < 0) {
|
|
*this += "<pipe(pipefd) failed with";
|
|
writeNum(errno);
|
|
*this += ">\n";
|
|
return;
|
|
}
|
|
// terminate child instead of waiting
|
|
{
|
|
struct sigaction act;
|
|
act.sa_handler = SIG_DFL;
|
|
sigemptyset(&act.sa_mask);
|
|
act.sa_flags = SA_NOCLDWAIT;
|
|
#ifdef SA_RESTORER
|
|
act.sa_restorer = NULL;
|
|
#endif
|
|
sigaction(SIGCHLD, &act, NULL);
|
|
}
|
|
pid_t pid = fork();
|
|
if (pid < 0) {
|
|
*this += "<fork() failed with ";
|
|
writeNum(errno);
|
|
*this += ">\n";
|
|
return;
|
|
}
|
|
if (pid == 0) {
|
|
close(pipefd[0]);
|
|
dup2(pipefd[1], STDOUT_FILENO);
|
|
char const* const argv[] = {"/bin/sh", "-c", cmd, NULL};
|
|
execv("/bin/sh", (char* const*)argv);
|
|
|
|
BufFileWriter<64> failmsg(pipefd[1]);
|
|
failmsg += "<execv(";
|
|
failmsg += cmd;
|
|
failmsg += ") resulted in errno ";
|
|
failmsg.write(errno);
|
|
failmsg += ">\n";
|
|
close(pipefd[1]);
|
|
abort();
|
|
} else {
|
|
close(pipefd[1]);
|
|
int len;
|
|
char readbuf[256];
|
|
while ((len = read(pipefd[0], readbuf, 256)) > 0) {
|
|
write(readbuf, len);
|
|
}
|
|
if (len < 0) {
|
|
*this += "<interrupted, read() resulted in errno ";
|
|
writeNum(errno);
|
|
*this += ">\n";
|
|
}
|
|
close(pipefd[0]);
|
|
}
|
|
}
|
|
void flush() {
|
|
size_t i = 0;
|
|
while (i < m_writeBufPos) {
|
|
int written = ::write(m_fd, m_writeBuf + i, m_writeBufPos - i);
|
|
if (written <= 0) {
|
|
return;
|
|
}
|
|
i += written;
|
|
}
|
|
m_writeBufPos = 0;
|
|
}
|
|
|
|
private:
|
|
char m_writeBuf[BUFSIZE];
|
|
size_t m_writeBufPos;
|
|
int m_fd;
|
|
};
|
|
|
|
char const* sig_getenv(char const* name);
|
|
|
|
char const* sig_strsignal(int sig);
|