summaryrefslogtreecommitdiff
path: root/src/imlib.c
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-05-11 15:03:24 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-05-11 15:03:24 +0200
commite28fb4e9d5723c46b8c3c91e94e9c5789b609d80 (patch)
tree687cbc4603bca2284c40b8dfcad6bc58e202a729 /src/imlib.c
parent4e2e218cf0fffd0c74aa4bd44d7abd318166403f (diff)
Use custom temporary directory for ImageMagick calls and clean it up afterwards
Diffstat (limited to 'src/imlib.c')
-rw-r--r--src/imlib.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/imlib.c b/src/imlib.c
index baaa64a..28dc1a6 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -304,8 +304,10 @@ static char *feh_magick_load_image(char *filename)
char *basename;
char *tmpname;
char *sfn;
+ char tempdir[] = "/tmp/.feh-magick-tmp-XXXXXX";
int fd = -1, devnull = -1;
int status;
+ char created_tempdir = 0;
if (opt.magick_timeout < 0)
return NULL;
@@ -339,6 +341,22 @@ static char *feh_magick_load_image(char *filename)
*/
argv_fn = estrjoin(":", "png", sfn, NULL);
+ /*
+ * By default, ImageMagick saves (occasionally lots of) temporary files
+ * in /tmp. It doesn't remove them if it runs into a timeout and is killed
+ * by us, no matter whether we use SIGINT, SIGTERM or SIGKILL. So, unless
+ * MAGICK_TMPDIR has already been set by the user, we create our own
+ * temporary directory for ImageMagick and remove its contents at the end of
+ * this function.
+ */
+ if (getenv("MAGICK_TMPDIR") == NULL) {
+ if (mkdtemp(tempdir) == NULL) {
+ weprintf("%s: ImageMagick may leave temporary files in /tmp. mkdtemp failed:", filename);
+ } else {
+ created_tempdir = 1;
+ }
+ }
+
if ((childpid = fork()) < 0) {
weprintf("%s: Can't load with imagemagick. Fork failed:", filename);
unlink(sfn);
@@ -360,6 +378,11 @@ static char *feh_magick_load_image(char *filename)
*/
setpgid(0, 0);
+ if (created_tempdir) {
+ // no error checking - this is a best-effort code path
+ setenv("MAGICK_TMPDIR", tempdir, 0);
+ }
+
execlp("convert", "convert", filename, argv_fn, NULL);
_exit(1);
}
@@ -373,13 +396,39 @@ static char *feh_magick_load_image(char *filename)
sfn = NULL;
if (!opt.quiet) {
- weprintf("%s - Conversion took too long, skipping", filename);
+ weprintf("%s: Conversion took too long, skipping", filename);
}
}
close(fd);
childpid = 0;
}
+ if (created_tempdir) {
+ DIR *dir;
+ struct dirent *de;
+ if ((dir = opendir(tempdir)) == NULL) {
+ weprintf("%s: Cannot remove temporary ImageMagick files from %s:", filename, tempdir);
+ } else {
+ while ((de = readdir(dir)) != NULL) {
+ if (de->d_name[0] != '.') {
+ char *temporary_file_name = estrjoin("/", tempdir, de->d_name, NULL);
+ /*
+ * We assume that ImageMagick only creates temporary files and
+ * not directories.
+ */
+ if (unlink(temporary_file_name) == -1) {
+ weprintf("unlink %s:", temporary_file_name);
+ }
+ free(temporary_file_name);
+ }
+ }
+ if (rmdir(tempdir) == -1) {
+ weprintf("rmdir %s:", tempdir);
+ }
+ }
+ closedir(dir);
+ }
+
free(argv_fn);
return sfn;
}