Skip to content

Commit

Permalink
Adding FIFO/pipe support ref. #5
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkeby committed Sep 7, 2021
1 parent 29f5e60 commit a5a2bea
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ version and further details on sxiv, how to install it and how it works.
### Changelog:
2021-09-07 - Added the fifo patch
2021-06-11 - Added the alpha patch
2021-06-10 - Added the "allow escape key in external key handler" patch (for the lack of a better
Expand Down Expand Up @@ -62,6 +64,9 @@ version and further details on sxiv, how to install it and how it works.
- [ewmh-wm-client-machine](https://github.com/muennich/sxiv/pull/403)
- sets the WM_CLIENT_MACHINE X property
- [fifo](https://github.com/muennich/sxiv/pull/369)
- adds support for pipe-based redirection for sxiv
- [image-mode-cycle](https://github.com/i-tsvetkov/sxiv-patches)
- adds the ability to cycle when viewing multiple images
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ HAVE_LIBEXIF = 1
#xrender = -lXrender

# Uncomment to enable SVG support / SVG_IMAGE_SUPPORT_PATCH
#svglibs = `pkg-config --cflags --libs librsvg-2.0 cairo`
svglibs = `pkg-config --cflags --libs librsvg-2.0 cairo`

# Uncomment to enable WebP support / WEBP_IMAGE_SUPPORT_PATCH
#webplibs = -lwebpdemux -lwebp
webplibs = -lwebpdemux -lwebp

# Uncomment to enable libcurl support / LIBCURL_PATCH
#curllibs = -lcurl
Expand Down
4 changes: 4 additions & 0 deletions image.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,11 @@ Imlib_Image img_open(const fileinfo_t *file)
stat(file->path, &st) == 0 && S_ISREG(st.st_mode))
{
#if WEBP_IMAGE_SUPPORT_PATCH
#if FIFO_PATCH
if (im == NULL && !strstr(file->name, "/proc/") && strcmp(file->name, "/dev/stdin"))
#else
if (im == NULL)
#endif // FIFO_PATCH
im = load_webp_firstframe_im(file);
#endif // WEBP_IMAGE_SUPPORT_PATCH

Expand Down
52 changes: 45 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ int filecnt, fileidx;
int alternate;
int markcnt;
int markidx;
#if LIBCURL_PATCH
#if LIBCURL_PATCH || FIFO_PATCH
char **rmfiles;
int rmcnt, rmidx;
#endif // LIBCURL_PATCH
#endif // LIBCURL_PATCH | FIFO_PATCH

int prefix;
bool extprefix;
Expand Down Expand Up @@ -115,9 +115,9 @@ CLEANUP void tmp_unlink(char **rmfiles, int n) {

void cleanup(void)
{
#if LIBCURL_PATCH
#if LIBCURL_PATCH || FIFO_PATCH
tmp_unlink(rmfiles, rmidx);
#endif // LIBCURL_PATCH
#endif // LIBCURL_PATCH | FIFO_PATCH
img_close(&img, false);
arl_cleanup(&arl);
tns_free(&tns);
Expand All @@ -130,18 +130,43 @@ void internal_check_add_file(char *filename, char *url, bool given)
void check_add_file(char *filename, bool given)
#endif // LIBCURL_PATCH
{
char *path;
char *path = NULL;
#if FIFO_PATCH
struct stat st;
bool rm = false;
#endif // FIFO_PATCH

if (*filename == '\0')
return;

#if FIFO_PATCH
if (access(filename, R_OK) == 0 && stat(filename, &st) == 0) {
switch (st.st_mode & S_IFMT) {
case S_IFREG:
path = realpath(filename, NULL);
break;

case S_IFIFO:
path = tmp_pipe_drain(filename);
rm = true;
break;
}
}

if (path == NULL) {
if (given)
error(0, errno, "%s", filename);
return;
}
#else
if (access(filename, R_OK) < 0 ||
(path = realpath(filename, NULL)) == NULL)
{
if (given)
error(0, errno, "%s", filename);
return;
}
#endif // FIFO_PATCH

if (fileidx == filecnt) {
filecnt *= 2;
Expand All @@ -166,6 +191,18 @@ void check_add_file(char *filename, bool given)
if (given)
files[fileidx].flags |= FF_WARN;
fileidx++;

#if FIFO_PATCH
if (rm) {
if (rmidx == rmcnt) {
rmcnt *= 2;
rmfiles = erealloc(rmfiles, rmcnt * sizeof(char*));
memset(&rmfiles[rmcnt/2], 0, rmcnt/2 * sizeof(char*));
}

rmfiles[rmidx++] = path;
}
#endif // FIFO_PATCH
}

#if LIBCURL_PATCH
Expand Down Expand Up @@ -961,11 +998,12 @@ int main(int argc, char **argv)
files = emalloc(filecnt * sizeof(*files));
memset(files, 0, filecnt * sizeof(*files));
fileidx = 0;
#if LIBCURL_PATCH

#if LIBCURL_PATCH || FIFO_PATCH
rmcnt = 16;
rmfiles = emalloc(rmcnt * sizeof(char*));
rmidx = 0;
#endif // LIBCURL_PATCH
#endif // LIBCURL_PATCH | FIFO_PATCH

if (options->from_stdin) {
n = 0;
Expand Down
14 changes: 14 additions & 0 deletions patches.def.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@
*/
#define EWMH_WM_CLIENT_MACHINE 0

/* Adds support for pipe-based redirection for sxiv.
*
* Example commands:
* $ sxiv <(curl -s https://i.imgur.com/JdfIbt4g.png) <(curl -s https://i.imgur.com/WwcW92d.png)
* $ curl -s https://i.imgur.com/JdfIbt4g.png | sxiv /dev/stdin
*
* This is not possible out of the box because FIFO/pipe files are not seekable which breaks
* things. The patch works around this by draining the pipe to a temporary file which is displayed
* and unlinked on exit.
*
* https://github.com/muennich/sxiv/pull/369
*/
#define FIFO_PATCH 0

/* Adds the ability to cycle when viewing multiple images.
* https://github.com/i-tsvetkov/sxiv-patches
*/
Expand Down
4 changes: 4 additions & 0 deletions sxiv.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ int r_opendir(r_dir_t*, const char*, bool);
int r_closedir(r_dir_t*);
char* r_readdir(r_dir_t*, bool);
int r_mkdir(char*);
#if FIFO_PATCH
char* tmp_pipe_drain(char*);
CLEANUP void tmp_unlink(char**, int);
#endif // FIFO_PATCH


/* window.c */
Expand Down
34 changes: 34 additions & 0 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,37 @@ int r_mkdir(char *path)
return 0;
}

#if FIFO_PATCH
char *tmp_pipe_drain(char *pipe)
{
int n;
char buf[1024];
char *path = emalloc(PATH_MAX);
int fd;

snprintf(path, PATH_MAX, "/tmp/sxiv-XXXXXX");
if ((fd = mkstemp(path)) < 0) {
free(path);
return NULL;
}

FILE *src = fopen(pipe, "rb");
FILE *dst = fdopen(fd, "wb");

while ((n = fread(buf, sizeof(char), sizeof(buf), src)) > 0) {
if (fwrite(buf, sizeof(char), n, dst) < n) {
free(path);
return NULL;
}
}

fclose(dst);
fclose(src);
return path;
}

CLEANUP void tmp_unlink(char **rmfiles, int n) {
while (n--)
unlink(rmfiles[n]);
}
#endif // FIFO_PATCH

0 comments on commit a5a2bea

Please sign in to comment.