Crashlog: Support gdb read when /dev/null is missing

pull/393/head
Jonathan G Rennison 2 years ago
parent d83f0d0cda
commit 220390ed3e

@ -72,16 +72,66 @@ static void LogStacktraceSigSegvHandler(int sig)
}
#endif
static int GetTemporaryFD()
{
char name[MAX_PATH];
extern std::string _personal_dir;
seprintf(name, lastof(name), "%sopenttd-tmp-XXXXXX", _personal_dir.c_str());
int fd = mkstemp(name);
if (fd != -1) {
/* Unlink file but leave fd open until finished with */
unlink(name);
}
return fd;
}
struct ExecReadNullHandler {
int fd[2] = { -1, -1 };
bool Init() {
this->fd[0] = open("/dev/null", O_RDWR);
if (this->fd[0] == -1) {
this->fd[0] = GetTemporaryFD();
if (this->fd[0] == -1) {
return false;
}
this->fd[1] = GetTemporaryFD();
if (this->fd[1] == -1) {
this->Close();
return false;
}
} else {
this->fd[1] = this->fd[0];
}
return true;
}
void Close() {
if (this->fd[0] != -1) close(this->fd[0]);
if (this->fd[1] != -1 && this->fd[0] != this->fd[1]) close(this->fd[1]);
this->fd[0] = -1;
this->fd[1] = -1;
}
};
static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, const char *last)
{
int null_fd = open("/dev/null", O_RDWR);
if (null_fd == -1) return false;
ExecReadNullHandler nulls;
if (!nulls.Init()) return false;
int pipefd[2];
if (pipe(pipefd) == -1) return false;
if (pipe(pipefd) == -1) {
nulls.Close();
return false;
}
int pid = fork();
if (pid < 0) return false;
if (pid < 0) {
nulls.Close();
close(pipefd[0]);
close(pipefd[1]);
return false;
}
if (pid == 0) {
/* child */
@ -89,9 +139,9 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
close(pipefd[0]); /* Close unused read end */
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
dup2(null_fd, STDERR_FILENO);
dup2(null_fd, STDIN_FILENO);
close(null_fd);
dup2(nulls.fd[0], STDERR_FILENO);
dup2(nulls.fd[1], STDIN_FILENO);
nulls.Close();
execvp(file, args);
exit(42);
@ -99,7 +149,7 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
/* parent */
close(null_fd);
nulls.Close();
close(pipefd[1]); /* Close unused write end */
while (buffer < last) {
@ -130,24 +180,18 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
static bool ExecReadStdoutThroughFile(const char *file, char *const *args, char *&buffer, const char *last)
{
int null_fd = open("/dev/null", O_RDWR);
if (null_fd == -1) return false;
ExecReadNullHandler nulls;
if (!nulls.Init()) return false;
char name[MAX_PATH];
extern std::string _personal_dir;
seprintf(name, lastof(name), "%sopenttd-tmp-XXXXXX", _personal_dir.c_str());
int fd = mkstemp(name);
int fd = GetTemporaryFD();
if (fd == -1) {
close(null_fd);
nulls.Close();
return false;
}
/* Unlink file but leave fd open until finished with */
unlink(name);
int pid = fork();
if (pid < 0) {
close(null_fd);
nulls.Close();
close(fd);
return false;
}
@ -157,9 +201,9 @@ static bool ExecReadStdoutThroughFile(const char *file, char *const *args, char
dup2(fd, STDOUT_FILENO);
close(fd);
dup2(null_fd, STDERR_FILENO);
dup2(null_fd, STDIN_FILENO);
close(null_fd);
dup2(nulls.fd[0], STDERR_FILENO);
dup2(nulls.fd[1], STDIN_FILENO);
nulls.Close();
execvp(file, args);
exit(42);
@ -167,7 +211,7 @@ static bool ExecReadStdoutThroughFile(const char *file, char *const *args, char
/* parent */
close(null_fd);
nulls.Close();
int status;
int wait_ret = waitpid(pid, &status, 0);

Loading…
Cancel
Save