Commit 8f5bf736 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Experimental code to limit imagemagick convert runtime (see #82)

Problems so far:
* leaks zombie processes
* does not work when terminating feh with a signal (since the convert process
  is no longer in feh's process group)
parent cbab594f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -188,4 +188,7 @@ extern feh_menu *menu_main;
extern feh_menu *menu_close;
extern char *mode;		/* label for the current mode */

/* to terminate long-running children with SIGALRM */
extern int childpid;

#endif
+24 −6
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ int xinerama_screen;
int num_xinerama_screens;
#endif				/* HAVE_LIBXINERAMA */

int childpid;

static char *feh_http_load_image(char *url);
static char *feh_magick_load_image(char *filename);

@@ -253,7 +255,10 @@ static char *feh_magick_load_image(char *filename)
	char *tmpname;
	char *sfn;
	int fd = -1, devnull = -1;
	int pid, status;
	int status;

	if (opt.magick_timeout < 0)
		return NULL;

	basename = strrchr(filename, '/');

@@ -277,26 +282,39 @@ static char *feh_magick_load_image(char *filename)

	snprintf(argv_fd, sizeof(argv_fd), "png:fd:%d", fd);


	if ((pid = fork()) == 0) {
	if ((childpid = fork()) == 0) {

		/* discard convert output */
		devnull = open("/dev/null", O_WRONLY);
		dup2(devnull, 1);
		dup2(devnull, 2);

		/*
		 * convert only accepts SIGINT via killpg, a normal kill doesn't work
		 */
		if (opt.magick_timeout)
			setpgid(0, 0);

		execlp("convert", "convert", filename, argv_fd, NULL);
		exit(1);
	}
	else {
		waitpid(pid, &status, 0);
		alarm(opt.magick_timeout);
		waitpid(childpid, &status, 0);
		alarm(0);
		if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
			close(fd);
			unlink(sfn);
			sfn = NULL;

			if (!opt.quiet)
				weprintf("%s - No loader for that file format", filename);
			if (!opt.quiet) {
				if (WIFSIGNALED(status))
					weprintf("%s - Conversion took too long, skipping",
						filename);
				else
					weprintf("%s - No loader for that file format",
						filename);
			}
		}
	}

+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "timers.h"
#include "options.h"
#include "events.h"
#include "signals.h"
#include "wallpaper.h"

char **cmdargv = NULL;
@@ -48,6 +49,7 @@ int main(int argc, char **argv)
		init_x_and_imlib();
		init_keyevents();
		init_buttonbindings();
		setup_signal_handlers();
	}

	feh_event_init();
+0 −2
Original line number Diff line number Diff line
@@ -65,7 +65,5 @@ void init_multiwindow_mode(void)
		free(s);
	}

	setup_signal_handlers();

	return;
}
+5 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ void init_parse_options(int argc, char **argv)
	opt.display = 1;
	opt.aspect = 1;
	opt.slideshow_delay = 0.0;
	opt.magick_timeout = 10;
	opt.thumb_w = 60;
	opt.thumb_h = 60;
	opt.thumb_redraw = 10;
@@ -378,6 +379,7 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
		{"zoom"          , 1, 0, 205},
		{"no-screen-clip", 0, 0, 206},
		{"index-info"    , 1, 0, 207},
		{"magick-timeout", 1, 0, 208},
		{"caption-path"  , 1, 0, 'K'},
		{"action1"       , 1, 0, 209},
		{"action2"       , 1, 0, 210},
@@ -646,6 +648,9 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
		case 207:
			opt.index_info = estrdup(optarg);
			break;
		case 208:
			opt.magick_timeout = atoi(optarg);
			break;
		case 'K':
			opt.caption_path = estrdup(optarg);
			break;
Loading