[ncman] map up argument

This commit is contained in:
nick black 2021-12-04 11:38:57 -05:00 committed by nick black
parent 269bf361e7
commit 7f94e50e69

View File

@ -1,5 +1,11 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <getopt.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <notcurses/notcurses.h>
static void
@ -38,21 +44,66 @@ parse_args(int argc, char** argv){
return optind;
}
static unsigned char*
map_troff_data(int fd, size_t* len){
struct stat sbuf;
if(fstat(fd, &sbuf)){
return NULL;
}
// gzip has a 10-byte mandatory header
if(sbuf.st_size < 10){
return NULL;
}
unsigned char* buf = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if(buf == MAP_FAILED){
return NULL;
}
if(buf[0] == 0x1f && buf[1] == 0x8b && buf[2] == 0x08){
// FIXME gzipped!
munmap(buf, sbuf.st_size);
return NULL;
}
*len = sbuf.st_size;
return buf;
}
// find the man page, and inflate it if deflated
static unsigned char*
get_troff_data(const char *arg, size_t* len){
// FIXME we'll want to use the mandb. for now, require a full path.
int fd = open(arg, O_RDONLY | O_CLOEXEC);
if(fd < 0){
return NULL;
}
unsigned char* buf = map_troff_data(fd, len);
close(fd);
return buf;
}
static int
manloop(struct notcurses* nc, const char* arg){
size_t len;
unsigned char* buf = get_troff_data(arg, &len);
if(buf == NULL){
return -1;
}
unsigned dimy, dimx;
struct ncplane* stdn = notcurses_stddim_yx(nc, &dimy, &dimx);
ncplane_putstr(stdn, arg);
ncplane_printf(stdn, "read %s (%" PRIuPTR "B)", arg, len);
if(notcurses_render(nc)){
munmap(buf, len);
return -1;
}
uint32_t key;
ncinput ni;
while((key = notcurses_get(nc, NULL, &ni)) != (uint32_t)-1){
switch(key){
case 'q': return 0;
case 'q':
munmap(buf, len);
return 0;
}
}
munmap(buf, len);
return -1;
}