feh icon indicating copy to clipboard operation
feh copied to clipboard

Support POSIX TMPDIR environmental variable

Open hipcatkiss opened this issue 1 year ago • 0 comments

https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html

As of now usage of /tmp is hardcoded. Suggested patch:

diff --git a/src/Makefile b/src/Makefile
index 2968671..451c333 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -23,7 +23,8 @@ TARGETS = \
 	timers.c \
 	utils.c \
 	wallpaper.c \
-	winwidget.c
+	winwidget.c \
+	tmpdir.c
 
 ifeq (${exif},1)
 	TARGETS += \
diff --git a/src/filelist.c b/src/filelist.c
index a5ad890..7b75d0b 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -26,8 +26,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "feh.h"
 #include "filelist.h"
-#include "signals.h"
 #include "options.h"
+#include "signals.h"
+#include "tmpdir.h"
 
 #ifdef HAVE_LIBCURL
 #include <curl/curl.h>
@@ -160,10 +161,17 @@ static void add_stdin_to_filelist(void)
 {
 	char buf[1024];
 	size_t readsize;
-	char *sfn = estrjoin("_", "/tmp/feh_stdin", "XXXXXX", NULL);
-	int fd = mkstemp(sfn);
+    char *tmpdir;
+	char *sfn;
+	int fd;
 	FILE *outfile;
 
+    tmpdir = posix_tmpdir();
+    tmpdir = estrjoin("", tmpdir, "feh_stdin", NULL);
+    sfn = estrjoin("_", tmpdir, "XXXXXX", NULL);
+    fd = mkstemp(sfn);
+    free(tmpdir);
+
 	if (fd == -1) {
 		free(sfn);
 		weprintf("cannot read from stdin: mktemp:");
diff --git a/src/imlib.c b/src/imlib.c
index eb3f522..7faeedb 100644
--- a/src/imlib.c
+++ b/src/imlib.c
@@ -26,9 +26,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "feh.h"
 #include "filelist.h"
+#include "options.h"
 #include "signals.h"
+#include "tmpdir.h"
 #include "winwidget.h"
-#include "options.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -612,7 +613,7 @@ static char *feh_dcraw_load_image(char *filename)
 	else
 		basename++;
 
-	tmpname = feh_unique_filename("/tmp/", basename);
+	tmpname = feh_unique_filename(posix_tmpdir(), basename);
 
 	if (strlen(tmpname) > (NAME_MAX-6))
 		tmpname[NAME_MAX-7] = '\0';
@@ -665,11 +666,14 @@ static char *feh_magick_load_image(char *filename)
 	char *basename;
 	char *tmpname;
 	char *sfn;
-	char tempdir[] = "/tmp/.feh-magick-tmp-XXXXXX";
+	char *tempdir;
 	int fd = -1, devnull = -1;
 	int status;
 	char created_tempdir = 0;
 
+    tempdir = posix_tmpdir();
+    tempdir = estrjoin("", tempdir, ".feh-magick-tmp-XXXXXX", NULL);
+
 	if (opt.use_conversion_cache) {
 		if (!conversion_cache)
 			conversion_cache = gib_hash_new();
@@ -684,7 +688,7 @@ static char *feh_magick_load_image(char *filename)
 	else
 		basename++;
 
-	tmpname = feh_unique_filename("/tmp/", basename);
+	tmpname = feh_unique_filename(posix_tmpdir(), basename);
 
 	if (strlen(tmpname) > (NAME_MAX-6))
 		tmpname[NAME_MAX-7] = '\0';
@@ -851,7 +855,7 @@ static char *feh_http_load_image(char *url)
 		else
 			path = "";
 	} else
-		path = "/tmp/";
+		path = posix_tmpdir();
 
 	curl = curl_easy_init();
 	if (!curl) {
diff --git a/src/slideshow.c b/src/slideshow.c
index 3944a68..7c11203 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -26,10 +26,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "feh.h"
 #include "filelist.h"
-#include "timers.h"
-#include "winwidget.h"
 #include "options.h"
 #include "signals.h"
+#include "timers.h"
+#include "tmpdir.h"
+#include "winwidget.h"
 
 void init_slideshow_mode(void)
 {
@@ -455,7 +456,7 @@ char *feh_printf(char *str, feh_file * file, winwidget winwid)
 				if (filelist_tmppath != NULL) {
 					strncat(ret, filelist_tmppath, sizeof(ret) - strlen(ret) - 1);
 				} else {
-					filelist_tmppath = feh_unique_filename("/tmp/","filelist");
+					filelist_tmppath = feh_unique_filename(posix_tmpdir(),"filelist");
 					feh_write_filelist(filelist, filelist_tmppath);
 					strncat(ret, filelist_tmppath, sizeof(ret) - strlen(ret) - 1);
 				}
diff --git a/src/tmpdir.c b/src/tmpdir.c
new file mode 100644
index 0000000..bbe3ade
--- /dev/null
+++ b/src/tmpdir.c
@@ -0,0 +1,87 @@
+/* tmpdir.c
+
+Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "utils.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+char *posix_tmpdir(void) {
+    static char *tmpdir = NULL;
+    static char *default_tmpdir = "/tmp/";
+    static char is_set = 0;
+
+    if (is_set) {
+        return tmpdir;
+    }
+
+    tmpdir = getenv("TMPDIR");
+    if (tmpdir == NULL) {
+        goto error;
+    }
+
+    struct stat sb;
+    if (stat(tmpdir, &sb) == -1) {
+        weprintf("%s:", tmpdir);
+        goto error;
+    }
+
+    if (!S_ISDIR(sb.st_mode)) {
+        weprintf("%s: not a directory", tmpdir);
+        goto error;
+    }
+
+    if (access(tmpdir, R_OK | W_OK | X_OK) == -1) {
+        weprintf("%s:", tmpdir);
+        goto error;
+    }
+
+    size_t len;
+    char *buf;
+    len = strlen(tmpdir);
+    buf = tmpdir;
+    tmpdir = malloc(len + 2);
+    for (size_t i = 0; i < len; i++) {
+        tmpdir[i] = buf[i];
+    }
+
+    // a lot of other code relies on the trailing slash
+    if (tmpdir[len - 1] == '/') {
+        tmpdir[len] = '\0';
+    } else {
+        tmpdir[len] = '/';
+    }
+    tmpdir[len + 1] = '\0';
+
+    is_set = 1;
+    return tmpdir;
+    error:
+    tmpdir = default_tmpdir;
+    is_set = 1;
+    return tmpdir;
+}
diff --git a/src/tmpdir.h b/src/tmpdir.h
new file mode 100644
index 0000000..35ab96a
--- /dev/null
+++ b/src/tmpdir.h
@@ -0,0 +1,32 @@
+/* tmpdir.h
+
+Copyright (C) 1999-2003 Tom Gilbert.
+Copyright (C) 2010-2020 Birte Kristina Friesel.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software and its documentation and acknowledgment shall be
+given in the documentation and software packages that this Software was
+used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#ifndef FEH_TMPDIR_H
+#define FEH_TMPDIR_H
+
+char *posix_tmpdir(void);
+
+#endif

Maybe instead of using static it is better to define it globally and set in main ().

hipcatkiss avatar Nov 04 '24 12:11 hipcatkiss