mirror of https://github.com/ericonr/ef.git
Use poll(3) and self pipe for signal handling.
Actually safe to perform the terminal cleanup here. We keep using exit(3) and quick_exit(3) so that only one of them actually prints the results to the screen.
This commit is contained in:
parent
a0ce797775
commit
b734660c96
51
ef.c
51
ef.c
|
@ -7,6 +7,8 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
|
@ -17,6 +19,7 @@
|
||||||
static void endwin_void(void)
|
static void endwin_void(void)
|
||||||
{
|
{
|
||||||
endwin();
|
endwin();
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *final_name;
|
static const char *final_name;
|
||||||
|
@ -26,10 +29,10 @@ static void print_name(void)
|
||||||
if (stdout_save && final_name) fputs(final_name, stdout_save);
|
if (stdout_save && final_name) fputs(final_name, stdout_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void finish(int sig)
|
static int signal_pipe[2];
|
||||||
|
static void signal_handler(int signum)
|
||||||
{
|
{
|
||||||
(void)sig;
|
write(signal_pipe[1], &signum, sizeof signum);
|
||||||
quick_exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -38,6 +41,15 @@ int main()
|
||||||
|
|
||||||
const char delim = '\n';
|
const char delim = '\n';
|
||||||
|
|
||||||
|
if (pipe(signal_pipe)) {
|
||||||
|
perror("pipe");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (signal(SIGINT, signal_handler) || signal(SIGTERM, signal_handler)) {
|
||||||
|
perror("signal");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
struct str_array entries = { 0 };
|
struct str_array entries = { 0 };
|
||||||
read_entries_from_stream(&entries, delim, stdin);
|
read_entries_from_stream(&entries, delim, stdin);
|
||||||
/* fast exit cases */
|
/* fast exit cases */
|
||||||
|
@ -63,14 +75,18 @@ int main()
|
||||||
}
|
}
|
||||||
close(tty_fd);
|
close(tty_fd);
|
||||||
|
|
||||||
atexit(print_name);
|
enum { SIGNAL, STDIN, POLLFD_AMOUNT };
|
||||||
|
struct pollfd polls[POLLFD_AMOUNT] = {
|
||||||
|
[SIGNAL] = {signal_pipe[0], POLLIN, 0},
|
||||||
|
[STDIN] = {STDIN_FILENO, POLLIN, 0},
|
||||||
|
};
|
||||||
|
|
||||||
signal(SIGINT, finish);
|
atexit(print_name);
|
||||||
atexit(endwin_void);
|
|
||||||
at_quick_exit(endwin_void);
|
|
||||||
|
|
||||||
/* curses initialization */
|
/* curses initialization */
|
||||||
initscr();
|
initscr();
|
||||||
|
at_quick_exit(endwin_void);
|
||||||
|
atexit(endwin_void);
|
||||||
/* terminal configuration */
|
/* terminal configuration */
|
||||||
nonl();
|
nonl();
|
||||||
cbreak();
|
cbreak();
|
||||||
|
@ -117,7 +133,7 @@ int main()
|
||||||
WINDOW *prompt = newwin(1, 0, LINES - 1, 0);
|
WINDOW *prompt = newwin(1, 0, LINES - 1, 0);
|
||||||
if (!list || !prompt) {
|
if (!list || !prompt) {
|
||||||
perror("newwin");
|
perror("newwin");
|
||||||
exit(1);
|
quick_exit(1);
|
||||||
}
|
}
|
||||||
keypad(prompt, TRUE);
|
keypad(prompt, TRUE);
|
||||||
|
|
||||||
|
@ -144,6 +160,23 @@ int main()
|
||||||
/* index inside set of matches */
|
/* index inside set of matches */
|
||||||
size_t index_in_matched = 0;
|
size_t index_in_matched = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (poll(polls, POLLFD_AMOUNT, -1) < 0) {
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
|
||||||
|
perror("poll");
|
||||||
|
quick_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (polls[SIGNAL].revents & POLLIN) {
|
||||||
|
int signum;
|
||||||
|
read(polls[SIGNAL].fd, &signum, sizeof signum);
|
||||||
|
if (signum == SIGINT || signum == SIGTERM) {
|
||||||
|
quick_exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(polls[STDIN].revents & POLLIN)) continue;
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
cap = 1024;
|
cap = 1024;
|
||||||
name = xmalloc(cap);
|
name = xmalloc(cap);
|
||||||
|
@ -157,7 +190,7 @@ int main()
|
||||||
int c = wgetch(prompt);
|
int c = wgetch(prompt);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 27: /* Ctrl+[ or ESC */
|
case 27: /* Ctrl+[ or ESC */
|
||||||
exit(1);
|
quick_exit(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_ENTER:
|
case KEY_ENTER:
|
||||||
|
|
4
util.c
4
util.c
|
@ -26,12 +26,12 @@ void *xmalloc(size_t s) {
|
||||||
void *r = malloc(s);
|
void *r = malloc(s);
|
||||||
if (r) return r;
|
if (r) return r;
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
quick_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xrealloc(void *p, size_t s) {
|
void *xrealloc(void *p, size_t s) {
|
||||||
void *r = realloc(p, s);
|
void *r = realloc(p, s);
|
||||||
if (r) return r;
|
if (r) return r;
|
||||||
perror("realloc");
|
perror("realloc");
|
||||||
exit(1);
|
quick_exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue