Skip to content

Commit f058a8d

Browse files
committed
[notcurses] try to fix midescape handling
Related to #1609
1 parent 1445f87 commit f058a8d

File tree

5 files changed

+108
-51
lines changed

5 files changed

+108
-51
lines changed

src/base/lnav_log.cc

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@
7171

7272
#include "ansi_scrubber.hh"
7373
#include "auto_mem.hh"
74+
#include "auto_pid.hh"
7475
#include "enum_util.hh"
7576
#include "fs_util.hh"
7677
#include "lnav_log.hh"
78+
#include "notcurses/notcurses.h"
7779
#include "opt_util.hh"
78-
#include "auto_pid.hh"
7980

8081
static constexpr size_t BUFFER_SIZE = 256 * 1024;
8182
static constexpr size_t MAX_LOG_LINE_SIZE = 2 * 1024;
@@ -328,7 +329,7 @@ static struct {
328329
size_t lr_length;
329330
off_t lr_frag_start{BUFFER_SIZE};
330331
off_t lr_frag_end;
331-
char *lr_data{log_ring_data};
332+
char* lr_data{log_ring_data};
332333
} log_ring;
333334

334335
static constexpr const char* const LEVEL_NAMES[] = {
@@ -481,11 +482,24 @@ log_msg(lnav_log_level_t level,
481482
int line_number,
482483
const char* fmt,
483484
...)
485+
{
486+
va_list args;
487+
488+
va_start(args, fmt);
489+
log_msgv(level, src_file, line_number, fmt, args);
490+
va_end(args);
491+
}
492+
493+
void
494+
log_msgv(lnav_log_level_t level,
495+
const char* src_file,
496+
int line_number,
497+
const char* fmt,
498+
va_list args)
484499
{
485500
struct timeval curr_time;
486501
struct tm localtm;
487502
ssize_t prefix_size;
488-
va_list args;
489503
ssize_t rc;
490504

491505
if (level < lnav_log_level) {
@@ -508,7 +522,6 @@ log_msg(lnav_log_level_t level,
508522
src_file = last_slash;
509523
}
510524

511-
va_start(args, fmt);
512525
gettimeofday(&curr_time, nullptr);
513526
localtime_r(&curr_time.tv_sec, &localtm);
514527
auto line = log_alloc();
@@ -554,7 +567,6 @@ log_msg(lnav_log_level_t level,
554567
fwrite(line, 1, prefix_size + rc + 1, file);
555568
fflush(file);
556569
};
557-
va_end(args);
558570
}
559571

560572
void
@@ -797,8 +809,7 @@ Or, you can send the following file to {PACKAGE_BUGREPORT}:
797809
default: {
798810
int status;
799811

800-
while (wait(&status) < 0) {
801-
}
812+
while (wait(&status) < 0) {}
802813
break;
803814
}
804815
}
@@ -925,3 +936,41 @@ log_crash_recoverer::~log_crash_recoverer()
925936
CRASH_LIST().erase(iter);
926937
}
927938
}
939+
940+
extern "C"
941+
{
942+
void
943+
nclog(ncloglevel_e level, const char* file, int line, const char* fmt, ...)
944+
{
945+
lnav_log_level_t lnav_level = lnav_log_level_t::DEBUG;
946+
947+
switch (level) {
948+
case NCLOGLEVEL_SILENT:
949+
return;
950+
case NCLOGLEVEL_PANIC:
951+
case NCLOGLEVEL_FATAL:
952+
case NCLOGLEVEL_ERROR:
953+
lnav_level = lnav_log_level_t::ERROR;
954+
break;
955+
case NCLOGLEVEL_WARNING:
956+
lnav_level = lnav_log_level_t::WARNING;
957+
break;
958+
case NCLOGLEVEL_INFO:
959+
lnav_level = lnav_log_level_t::INFO;
960+
break;
961+
case NCLOGLEVEL_VERBOSE:
962+
case NCLOGLEVEL_DEBUG:
963+
lnav_level = lnav_log_level_t::DEBUG;
964+
break;
965+
case NCLOGLEVEL_TRACE:
966+
lnav_level = lnav_log_level_t::TRACE;
967+
break;
968+
}
969+
970+
va_list args;
971+
972+
va_start(args, fmt);
973+
log_msgv(lnav_level, file, line, fmt, args);
974+
va_end(args);
975+
}
976+
}

src/base/lnav_log.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ void log_rusage_raw(enum lnav_log_level_t level,
6969
# define LNAV_ATTR_FORMAT_PRINTF(a, b)
7070
#endif
7171

72+
void log_msgv(enum lnav_log_level_t level,
73+
const char* src_file,
74+
int line_number,
75+
const char* fmt,
76+
va_list args);
7277
void log_msg(enum lnav_log_level_t level,
7378
const char* src_file,
7479
int line_number,

src/lnav.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ force_linking(services::main_t anno)
295295

296296
lnav_data_t lnav_data;
297297

298+
static auto nc_debug = false;
299+
298300
bool
299301
setup_logline_table(exec_context& ec)
300302
{
@@ -1359,7 +1361,7 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
13591361

13601362
notcurses_options nco = {};
13611363
nco.flags |= NCOPTION_SUPPRESS_BANNERS | NCOPTION_NO_WINCH_SIGHANDLER;
1362-
nco.loglevel = NCLOGLEVEL_PANIC;
1364+
nco.loglevel = nc_debug ? NCLOGLEVEL_DEBUG : NCLOGLEVEL_PANIC;
13631365
auto create_screen_res = screen_curses::create(nco);
13641366

13651367
if (create_screen_res.isErr()) {
@@ -2748,7 +2750,8 @@ main(int argc, char* argv[])
27482750
auto& ec = lnav_data.ld_exec_context;
27492751
int retval = EXIT_SUCCESS;
27502752

2751-
bool exec_stdin = false, load_stdin = false;
2753+
auto exec_stdin = false;
2754+
auto load_stdin = false;
27522755
mode_flags_t mode_flags;
27532756
std::string since_time;
27542757
std::string until_time;
@@ -3072,6 +3075,7 @@ SELECT tbl_name FROM sqlite_master WHERE sql LIKE 'CREATE VIRTUAL TABLE%'
30723075
lnav_data.ld_debug_log_name,
30733076
"Write debug messages to the given file.")
30743077
->type_name("FILE");
3078+
app.add_flag("-D", nc_debug, "Enable debugging of notcurses");
30753079
app.add_option("-I", lnav_data.ld_config_paths, "include paths")
30763080
->check(CLI::ExistingDirectory)
30773081
->check([&arg_errors](std::string inc_path) -> std::string {

src/third-party/notcurses/src/lib/in.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ typedef HANDLE ipipe;
5353
typedef struct inputctx {
5454
// these two are not ringbuffers; we always move any leftover materia to the
5555
// front of the queue (it ought be a handful of bytes at most).
56-
unsigned char tbuf[BUFSIZ]; // only used if we have distinct terminal fd
57-
unsigned char ibuf[BUFSIZ]; // might be intermingled bulk/control data
56+
unsigned char tbuf[4096]; // only used if we have distinct terminal fd
57+
unsigned char ibuf[4096]; // might be intermingled bulk/control data
5858

5959
int stdinfd; // bulk in fd. always >= 0 (almost always 0). we do not
6060
// own this descriptor, and must not close() it.
@@ -2018,7 +2018,7 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, int rmargin,
20182018
i->looping = true;
20192019
i->csize = 64;
20202020
if( (i->csrs = malloc(sizeof(*i->csrs) * i->csize)) ){
2021-
i->isize = BUFSIZ;
2021+
i->isize = 4096;
20222022
if( (i->inputs = malloc(sizeof(*i->inputs) * i->isize)) ){
20232023
if(pthread_mutex_init(&i->ilock, NULL) == 0){
20242024
if(pthread_condmonotonic_init(&i->icond) == 0){
@@ -2241,25 +2241,29 @@ read_input_nblock(int fd, unsigned char* buf, size_t buflen, int *bufused,
22412241
if(space == 0){
22422242
return;
22432243
}
2244-
ssize_t r = read(fd, buf + *bufused, space);
2245-
if(r <= 0){
2246-
if(r < 0 && (errno != EAGAIN && errno != EBUSY && errno == EWOULDBLOCK)){
2247-
logwarn("couldn't read from %d (%s)", fd, strerror(errno));
2248-
}else{
2249-
if(r < 0){
2250-
logerror("error reading from %d (%s)", fd, strerror(errno));
2251-
}else{
2252-
logwarn("got EOF on %d", fd);
2253-
}
2254-
if(goteof){
2255-
*goteof = 1;
2256-
}
2244+
for (int attempts = 10; attempts > 0; --attempts) {
2245+
ssize_t r = read(fd, buf + *bufused, space);
2246+
if(r <= 0){
2247+
if(r < 0 && (errno != EAGAIN && errno != EBUSY && errno != EWOULDBLOCK)){
2248+
logwarn("couldn't read from %d (%s)", fd, strerror(errno));
2249+
}else{
2250+
if(r < 0){
2251+
logerror("error reading from %d (%s)", fd, strerror(errno));
2252+
usleep(1000);
2253+
continue;
2254+
}
2255+
logwarn("got EOF on %d", fd);
2256+
if (goteof) {
2257+
*goteof = 1;
2258+
}
2259+
}
2260+
return;
2261+
}
2262+
*bufused += r;
2263+
space -= r;
2264+
loginfo("read %" PRIdPTR "B from %d (%" PRIuPTR "B left)", r, fd, space);
2265+
return;
22572266
}
2258-
return;
2259-
}
2260-
*bufused += r;
2261-
space -= r;
2262-
loginfo("read %" PRIdPTR "B from %d (%" PRIuPTR "B left)", r, fd, space);
22632267
}
22642268

22652269
// are terminal and stdin distinct for this inputctx?
@@ -2464,7 +2468,7 @@ static void
24642468
process_melange(inputctx* ictx, const unsigned char* buf, int* bufused){
24652469
int offset = 0;
24662470
int origlen = *bufused;
2467-
while(*bufused){
2471+
while(*bufused && (origlen <= 32 || *bufused > 32)){
24682472
logdebug("input %d (%u)/%d [0x%02x] (%c)", offset, ictx->amata.used,
24692473
*bufused, buf[offset], isprint(buf[offset]) ? buf[offset] : ' ');
24702474
int consumed = 0;
@@ -2473,7 +2477,7 @@ process_melange(inputctx* ictx, const unsigned char* buf, int* bufused){
24732477
if(consumed < 0){
24742478
if(ictx->midescape){
24752479
if(*bufused != -consumed || consumed == -1){
2476-
logdebug("not midescape bufused=%d origlen=%d", *bufused, origlen);
2480+
logdebug("not midescape bufused=%d origlen=%d consumed=%d", *bufused, origlen, consumed);
24772481
// not at the end; treat it as input. no need to move between
24782482
// buffers; simply ensure we process it as input, and don't mark
24792483
// anything as consumed.
@@ -2648,13 +2652,13 @@ block_on_input(inputctx* ictx, unsigned* rtfd, unsigned* rifd){
26482652
int events;
26492653
#if defined(__APPLE__)
26502654
loginfo("select maxfd %d", maxfd);
2651-
struct timeval ts = {1, 0};
2655+
struct timeval ts = { ictx->ibufvalid == 0 ? 1 : 0, ictx->ibufvalid == 0 ? 0 : 10000};
26522656
while ((events = select(maxfd + 1, &rfds, NULL, NULL, &ts)) <0) {
26532657
# elif defined(__MINGW32__)
26542658
int timeoutms = nonblock ? 0 : -1;
26552659
while((events = poll(pfds, pfdcount, timeoutms)) < 0){ // FIXME smask?
26562660
#else
2657-
struct timespec ts = { .tv_sec = 1, .tv_nsec = 0, };
2661+
struct timespec ts = { .tv_sec = ictx->ibufvalid == 0 ? 1 : 0, .tv_nsec = ictx->ibufvalid == 0 ? 0 : 10000000, };
26582662
struct timespec* pts = nonblock ? &ts : NULL;
26592663
while((events = ppoll(pfds, pfdcount, pts, &smask)) < 0){
26602664
#endif

src/third-party/notcurses/src/lib/logging.h

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,55 +8,50 @@ extern "C" {
88
// logging
99
extern ncloglevel_e loglevel;
1010

11-
static inline void nclog(const char* fmt, ...)
12-
__attribute__ ((format (printf, 1, 2)));
11+
void nclog(ncloglevel_e level, const char* file, int line, const char* fmt, ...)
12+
__attribute__ ((format (printf, 4, 5)));
1313

14-
static inline void
15-
nclog(const char* fmt, ...){
16-
va_list va;
17-
va_start(va, fmt);
18-
vfprintf(stderr, fmt, va);
19-
va_end(va);
20-
}
14+
void
15+
nclog(ncloglevel_e level, const char* file, int line, const char* fmt, ...);
2116

2217
#define logpanic(fmt, ...) do{ \
2318
if(loglevel >= NCLOGLEVEL_PANIC){ \
24-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
19+
nclog(NCLOGLEVEL_PANIC, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
2520
} while(0);
2621

2722
#define logfatal(fmt, ...) do{ \
2823
if(loglevel >= NCLOGLEVEL_FATAL){ \
29-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
24+
nclog(NCLOGLEVEL_FATAL, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
3025
} while(0);
3126

3227
#define logerror(fmt, ...) do{ \
3328
if(loglevel >= NCLOGLEVEL_ERROR){ \
34-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
29+
nclog(NCLOGLEVEL_ERROR, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
3530
} while(0);
3631

3732
#define logwarn(fmt, ...) do{ \
3833
if(loglevel >= NCLOGLEVEL_WARNING){ \
39-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
34+
nclog(NCLOGLEVEL_WARNING, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
4035
} while(0);
4136

4237
#define loginfo(fmt, ...) do{ \
4338
if(loglevel >= NCLOGLEVEL_INFO){ \
44-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
39+
nclog(NCLOGLEVEL_INFO, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
4540
} while(0);
4641

4742
#define logverbose(fmt, ...) do{ \
4843
if(loglevel >= NCLOGLEVEL_VERBOSE){ \
49-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
44+
nclog(NCLOGLEVEL_VERBOSE, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
5045
} while(0);
5146

5247
#define logdebug(fmt, ...) do{ \
5348
if(loglevel >= NCLOGLEVEL_DEBUG){ \
54-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
49+
nclog(NCLOGLEVEL_DEBUG, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
5550
} while(0);
5651

5752
#define logtrace(fmt, ...) do{ \
5853
if(loglevel >= NCLOGLEVEL_TRACE){ \
59-
nclog("%s:%d:" fmt NL, __func__, __LINE__, ##__VA_ARGS__); } \
54+
nclog(NCLOGLEVEL_TRACE, __func__, __LINE__, fmt, ##__VA_ARGS__); } \
6055
} while(0);
6156

6257
#ifdef __cplusplus

0 commit comments

Comments
 (0)