commit - d781a4b951c9c8907ef753c24cc776bc145db121
commit + 7896cfae35cc018c6858ed5dbbbd361f3ba86ffe
blob - 630e50c714c4bfbf204f1aee0856d972fd3e0f48
blob + 19262fbbff20e15e8f7741c37934db5df8b16766
--- rover.c
+++ rover.c
free(marks->entries);
}
-static void message(const char *msg, Color color);
-static void clear_message();
+static void update_view();
-static void handle_segv(int sig);
-static void handle_winch(int sig);
+/* SIGSEGV handler: clean up curses before exiting. */
+static void
+handle_segv(int sig)
+{
+ (void) sig;
+ endwin();
+ fprintf(stderr, "Received SIGSEGV (segmentation fault).\n");
+ exit(1);
+}
-/* Curses setup. */
+/* SIGWINCH handler: resize application according to new terminal settings. */
static void
-init_term()
+handle_winch(int sig)
{
+ (void) sig;
+ delwin(rover.window);
+ endwin();
+ refresh();
+ clear();
+ rover.window = subwin(stdscr, LINES - 2, COLS, 1, 0);
+ update_view();
+}
+
+static void
+enable_handlers()
+{
struct sigaction sa;
+ memset(&sa, 0, sizeof (struct sigaction));
+ sa.sa_handler = handle_segv;
+ sigaction(SIGSEGV, &sa, NULL);
+ sa.sa_handler = handle_winch;
+ sigaction(SIGWINCH, &sa, NULL);
+}
+
+static void
+disable_handlers()
+{
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof (struct sigaction));
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGWINCH, &sa, NULL);
+}
+
+/* Do a fork-exec to external program (e.g. $EDITOR). */
+static void
+spawn()
+{
+ pid_t pid;
+ int status;
+
+ pid = fork();
+ if (pid > 0) {
+ /* fork() succeeded. */
+ disable_handlers();
+ endwin();
+ waitpid(pid, &status, 0);
+ enable_handlers();
+ kill(getpid(), SIGWINCH);
+ } else if (pid == 0) {
+ /* Child process. */
+ execvp(ARGS[0], ARGS);
+ }
+}
+
+/* Curses setup. */
+static void
+init_term()
+{
setlocale(LC_ALL, "");
initscr();
cbreak(); /* Get one character at a time. */
init_pair(WHITE, COLOR_WHITE, bg);
}
atexit((void (*)(void)) endwin);
- memset(&sa, 0, sizeof (struct sigaction));
- /* Setup SIGSEGV handler. */
- sa.sa_handler = handle_segv;
- sigaction(SIGSEGV, &sa, NULL);
- /* Setup SIGWINCH handler. */
- sa.sa_handler = handle_winch;
- sigaction(SIGWINCH, &sa, NULL);
+ enable_handlers();
}
/* Update the listing view. */
wrefresh(rover.window);
}
-/* SIGSEGV handler: clean up curses before exiting. */
-static void
-handle_segv(int sig)
+/* Show a message on the status bar. */
+static void
+message(const char *msg, Color color)
{
- (void) sig;
- endwin();
- fprintf(stderr, "Received SIGSEGV (segmentation fault).\n");
- exit(1);
+ int len, pos;
+
+ len = strlen(msg);
+ pos = (STATUSPOS - len) >> 1;
+ attr_on(A_BOLD, NULL);
+ color_set(color, NULL);
+ mvaddstr(LINES - 1, pos, msg);
+ color_set(DEFAULT, NULL);
+ attr_off(A_BOLD, NULL);
}
-/* SIGWINCH handler: resize application according to new terminal settings. */
+/* Clear message area, leaving only status info. */
static void
-handle_winch(int sig)
+clear_message()
{
- (void) sig;
- delwin(rover.window);
- endwin();
- refresh();
- clear();
- rover.window = subwin(stdscr, LINES - 2, COLS, 1, 0);
- update_view();
+ mvhline(LINES - 1, 0, ' ', STATUSPOS);
}
/* Comparison used to sort listing entries. */
return ret;
}
-/* Do a fork-exec to external program (e.g. $EDITOR). */
-static void
-spawn()
-{
- pid_t pid;
- int status;
- struct sigaction sa;
-
- pid = fork();
- if (pid > 0) {
- /* fork() succeeded. */
- memset(&sa, 0, sizeof (struct sigaction));
- sa.sa_handler = SIG_DFL;
- sigaction(SIGSEGV, &sa, NULL);
- sigaction(SIGWINCH, &sa, NULL);
- endwin();
- waitpid(pid, &status, 0);
- init_term();
- handle_winch(0);
- } else if (pid == 0) {
- /* Child process. */
- execvp(ARGS[0], ARGS);
- }
-}
-
/* Interactive getstr(). */
static int
igetstr(char *buffer, int maxlen)
color_set(DEFAULT, NULL);
}
-/* Show a message on the status bar. */
-static void
-message(const char *msg, Color color)
-{
- int len, pos;
-
- len = strlen(msg);
- pos = (STATUSPOS - len) >> 1;
- attr_on(A_BOLD, NULL);
- color_set(color, NULL);
- mvaddstr(LINES - 1, pos, msg);
- color_set(DEFAULT, NULL);
- attr_off(A_BOLD, NULL);
-}
-
-/* Clear message area, leaving only status info. */
-static void
-clear_message()
-{
- mvhline(LINES - 1, 0, ' ', STATUSPOS);
-}
-
int
main(int argc, char *argv[])
{