mirror of https://github.com/xzeldon/htop.git
Cache stderr to be able to print assert messages
This commit is contained in:
parent
64a1ab848f
commit
7b1fa1bf49
93
CRT.c
93
CRT.c
|
@ -24,6 +24,10 @@ in the source distribution for its full text.
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NDEBUG) && defined(HAVE_MEMFD_CREATE)
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define ColorIndex(i,j) ((7-(i))*8+(j))
|
#define ColorIndex(i,j) ((7-(i))*8+(j))
|
||||||
|
|
||||||
|
@ -685,9 +689,96 @@ void CRT_restorePrivileges() {
|
||||||
|
|
||||||
#endif /* HAVE_SETUID_ENABLED */
|
#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];
|
static struct sigaction old_sig_handler[32];
|
||||||
|
|
||||||
void CRT_init(const Settings* settings, bool allowUnicode) {
|
void CRT_init(const Settings* settings, bool allowUnicode) {
|
||||||
|
redirectStderr();
|
||||||
|
|
||||||
initscr();
|
initscr();
|
||||||
noecho();
|
noecho();
|
||||||
CRT_delay = &(settings->delay);
|
CRT_delay = &(settings->delay);
|
||||||
|
@ -788,6 +879,8 @@ void CRT_init(const Settings* settings, bool allowUnicode) {
|
||||||
void CRT_done() {
|
void CRT_done() {
|
||||||
curs_set(1);
|
curs_set(1);
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
|
dumpStderr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRT_fatalError(const char* note) {
|
void CRT_fatalError(const char* note) {
|
||||||
|
|
|
@ -189,6 +189,7 @@ AC_CHECK_FUNCS([ \
|
||||||
faccessat \
|
faccessat \
|
||||||
fstatat \
|
fstatat \
|
||||||
host_get_clock_service \
|
host_get_clock_service \
|
||||||
|
memfd_create\
|
||||||
openat \
|
openat \
|
||||||
readlinkat \
|
readlinkat \
|
||||||
])
|
])
|
||||||
|
|
Loading…
Reference in New Issue