commit - f5c33c313c5227101bded81f03ce4820005472fa
commit + 329cd624ab8a6f91ae66a4b8d554a418950926af
blob - b2668e4631c9f18cf9814a7b1eb1f65e8cf2a357
blob + 0da2d4a759b22e77d116dd27461460787942aaaa
--- ui.c
+++ ui.c
#include <curses.h>
#include <errno.h>
+#include <fcntl.h>
#include <locale.h>
#include <signal.h>
#include <stdarg.h>
#include "ui.h"
#include "utf8.h"
+enum exec_mode {
+ EXEC_FOREGROUND,
+ EXEC_BACKGROUND,
+};
+
static void set_scroll_position(struct tab *, size_t, size_t);
static void restore_curs_x(struct buffer *);
static int readkey(void);
static void dispatch_stdio(int, int, void*);
-static void handle_resize(int, int, void*);
+static void handle_signal(int, int, void*);
static void handle_resize_nodelay(int, int, void*);
static void handle_download_refresh(int, int, void *);
static void rearrange_windows(void);
static void redraw_tab(struct tab*);
static void update_loading_anim(int, int, void*);
static void stop_loading_anim(struct tab*);
-static int exec_external_cmd(char **);
+static int exec_external_cmd(char **, enum exec_mode);
static int should_rearrange_windows;
static int show_tab_bar;
}
static void
-handle_resize(int sig, int ev, void *d)
+handle_signal(int sig, int ev, void *d)
{
- ev_timer_cancel(resize_timer);
- resize_timer = ev_timer(&resize_tv, handle_resize_nodelay, NULL);
+ int ret;
+
+ switch (sig) {
+ case SIGWINCH:
+ ev_timer_cancel(resize_timer);
+ resize_timer = ev_timer(&resize_tv, handle_resize_nodelay,
+ NULL);
+ break;
+ case SIGCHLD:
+ do {
+ ret = waitpid(-1, NULL, WNOHANG);
+ } while (ret == -1 && errno == EINTR);
+ break;
+ }
}
static void
void
ui_main_loop(void)
{
- if (ev_signal(SIGWINCH, handle_resize, NULL) == -1 ||
+ if (ev_signal(SIGWINCH, handle_signal, NULL) == -1 ||
+ ev_signal(SIGCHLD, handle_signal, NULL) == -1 ||
ev_add(0, EV_READ, dispatch_stdio, NULL) == -1)
err(1, "ev_signal or ev_add failed");
ui_prompt_download_cmd(char *path, char *mime_type)
{
struct mailcap *mc = NULL;
+ enum exec_mode mode = EXEC_BACKGROUND;
if ((mc = mailcap_cmd_from_mimetype(mime_type, path)) == NULL)
return;
+ if (mc->flags & MAILCAP_NEEDSTERMINAL)
+ mode = EXEC_FOREGROUND;
+
message("Loaded %s with %s", mime_type, mc->cmd_argv[0]);
- exec_external_cmd(mc->cmd_argv);
+ exec_external_cmd(mc->cmd_argv, mode);
}
void
}
static int
-exec_external_cmd(char **argv)
+exec_external_cmd(char **argv, enum exec_mode mode)
{
char **t;
- int s, ret;
+ int s, fd, ret;
pid_t pid;
if (argv == NULL)
return (-1);
- endwin();
+ if (mode == EXEC_FOREGROUND) {
+ endwin();
- fprintf(stderr, "%s: running", getprogname());
- for (t = argv; *t; ++t)
- fprintf(stderr, " %s", *t);
- fprintf(stderr, "\n");
- fflush(NULL);
+ fprintf(stderr, "%s: running", getprogname());
+ for (t = argv; *t; ++t)
+ fprintf(stderr, " %s", *t);
+ fprintf(stderr, "\n");
+ fflush(NULL);
+ }
switch (pid = fork()) {
case -1:
message("failed to fork: %s", strerror(errno));
return (-1);
case 0:
+ if (mode == EXEC_BACKGROUND) {
+ if ((fd = open("/dev/null", O_RDWR)) == -1) {
+ warn("can't open /dev/null");
+ _exit(1);
+ }
+ (void)dup2(fd, 0);
+ (void)dup2(fd, 1);
+ (void)dup2(fd, 2);
+ if (fd > 2)
+ close(fd);
+ }
execvp(argv[0], argv);
- warn("can't exec \"%s\"", argv[0]);
- fprintf(stderr, "Press enter to continue");
- fflush(stderr);
- read(0, &s, 1);
+ if (mode == EXEC_FOREGROUND) {
+ warn("can't exec \"%s\"", argv[0]);
+ fprintf(stderr, "Press enter to continue");
+ fflush(stderr);
+ read(0, &s, 1);
+ }
_exit(1);
}
+ if (mode == EXEC_BACKGROUND)
+ return (0);
+
do {
ret = waitpid(pid, &s, 0);
} while (ret == -1 && errno == EINTR);
argv[1] = sfn;
argv[2] = NULL;
- if (exec_external_cmd(argv) == -1) {
+ if (exec_external_cmd(argv, EXEC_FOREGROUND) == -1) {
(void) unlink(sfn);
return;
}