Cache stderr to be able to print assert messages

This commit is contained in:
Christian Göttsche 2020-12-25 11:03:15 +01:00
parent 64a1ab848f
commit 7b1fa1bf49
2 changed files with 94 additions and 0 deletions

93
CRT.c
View File

@ -24,6 +24,10 @@ in the source distribution for its full text.
#include <execinfo.h>
#endif
#if !defined(NDEBUG) && defined(HAVE_MEMFD_CREATE)
#include <sys/mman.h>
#endif
#define ColorIndex(i,j) ((7-(i))*8+(j))
@ -685,9 +689,96 @@ void CRT_restorePrivileges() {
#endif /* HAVE_SETUID_ENABLED */
#ifndef NDEBUG
static int stderrRedirectNewFd = -1;
static int stderrRedirectBackupFd = -1;
static int createStderrCacheFile(void) {
#ifdef HAVE_MEMFD_CREATE
return memfd_create("htop.stderr-redirect", 0);
#elif defined(O_TMPFILE)
return open("/tmp", O_TMPFILE | O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
#else
char tmpName[] = "htop.stderr-redirectXXXXXX";
mode_t curUmask = umask(S_IXUSR | S_IRWXG | S_IRWXO);
int r = mkstemp(tmpName);
umask(curUmask);
if (r < 0)
return r;
(void) unlink(tmpName);
return r;
#endif /* HAVE_MEMFD_CREATE */
}
static void redirectStderr(void) {
stderrRedirectNewFd = createStderrCacheFile();
if (stderrRedirectNewFd < 0) {
/* ignore failure */
return;
}
stderrRedirectBackupFd = dup(STDERR_FILENO);
dup2(stderrRedirectNewFd, STDERR_FILENO);
}
static void dumpStderr(void) {
if (stderrRedirectNewFd < 0)
return;
fsync(STDERR_FILENO);
dup2(stderrRedirectBackupFd, STDERR_FILENO);
lseek(stderrRedirectNewFd, 0, SEEK_SET);
bool header = false;
char buffer[8192];
for (;;) {
errno = 0;
ssize_t res = read(stderrRedirectNewFd, buffer, sizeof(buffer));
if (res < 0) {
if (errno == EINTR)
continue;
break;
}
if (res == 0) {
break;
}
if (res > 0) {
if (!header) {
fprintf(stderr, ">>>>>>>>>> stderr output >>>>>>>>>>\n\n");
header = true;
}
(void)! write(STDERR_FILENO, buffer, res);
}
}
if (header)
fprintf(stderr, "\n<<<<<<<<<< stderr output <<<<<<<<<<\n");
close(stderrRedirectNewFd);
stderrRedirectNewFd = -1;
}
#else /* !NDEBUG */
static void redirectStderr(void) {
}
static void dumpStderr(void) {
}
#endif /* !NDEBUG */
static struct sigaction old_sig_handler[32];
void CRT_init(const Settings* settings, bool allowUnicode) {
redirectStderr();
initscr();
noecho();
CRT_delay = &(settings->delay);
@ -788,6 +879,8 @@ void CRT_init(const Settings* settings, bool allowUnicode) {
void CRT_done() {
curs_set(1);
endwin();
dumpStderr();
}
void CRT_fatalError(const char* note) {

View File

@ -189,6 +189,7 @@ AC_CHECK_FUNCS([ \
faccessat \
fstatat \
host_get_clock_service \
memfd_create\
openat \
readlinkat \
])