Skip to content

Conversation

@bergmannf
Copy link

Instead of always using stdin and creating a tempfile, this argument will allow using a file passed by the user instead.

This can be useful for integrating into other programs, that don't want to start a subshell to use pipes: e.g. in my case I want to use https://github.com/jkitchin/ox-clip and replace the current xclip by wl-copy but that needs wl-copy to accept a file argument.

Instead of always using stdin and creating a tempfile, this argument
will use a file passed by the user instead.

This can be useful for integrating into other programs, that don't want
to start a subshell to use pipes.
@bugaevc
Copy link
Owner

bugaevc commented Jun 3, 2025

Hi, while we could do something like this, I'm not seeing why it's needed for your use case at all:

This can be useful for integrating into other programs, that don't want to start a subshell to use pipes

You shouldn't need a subshell or a pipe just to pass a file as a standard input stream to a subprocess. Just... pass it. if you're doing raw Unix, it goes something like this:

pid = fork();
if (pid == 0) {
    // child
    dup2(input_file_fd, STDIN_FILENO);
    close(input_file_fd);
    exec("the-child");
} else {
    close(input_file_fd);
    ...
}

If you're using something higher-level, there should normally be a way to configure what gets passed as standard I/O streams. For instance in Python subprocess that's stdin=, stdout=, stderr=.

in my case I want to use https://github.com/jkitchin/ox-clip and replace the current xclip by wl-copy but that needs wl-copy to accept a file argument

I readily admit that I'm not very familiar with the Emacs API, but it sounds like shell-command-on-region already does the right thing, i.e. it passes the contents of the selected region as standard input to the command. ox-clip already uses shell-command-on-region for everything but xlip, with a comment saying "For some reason shell-command on region does not work with xclip"; instead it explicitly creates a temp file and passes its path to xclip.

So one way for you to integrate wl-copy is to just make it use shell-command-on-region like it does for other backends, and see if that works (and maybe report it back to me if it doesn't). Another would be to do the explicit temp file creation as done for xclip, but pass that as stdin, and not a file name, to wl-copy; this will likely require you to replace start-process with call-process.

@bergmannf
Copy link
Author

Wow - thanks for the really in-depth research you did for this.
I did check what happens when I try to run wl-copy using shell-command-on-region and surprisingly it just hangs - but once I cancel the process it did copy what I wanted to the clipboard.

So I went digging to see why it hangs, and I think the problem is that emacs actually passes the stderr fd as a pipe - I did strace both wl-copy and emacs when it hung and saw the following results:

  1. The wl-copy end:
strace -p 12226
strace: Process 12226 attached
restart_syscall(<... resuming interrupted poll ...
  1. The emacs end:
read(24, 0x7ffe5bf08450, 16384)         = ? ERESTARTSYS (To be restarted if SA_RESTART is set)

(The emacs output contains a lot more stuff obviously, but that is the interesting one).

So checking what this fd is, it shows up as a pipe:

le /proc/4913/fd
lr-x------@ - florian  4 Jun 20:18  24 -> pipe:[71649]

And for wl-copy that is the stderr filehandle:

le /proc/12226/fd
lrwx------@ - florian  4 Jun 20:19  0 -> /dev/null
lrwx------@ - florian  4 Jun 20:19  1 -> /dev/null
l-wx------@ - florian  4 Jun 20:19  2 -> pipe:[71649]

I did compile a version of wl-copy where I just check if stderr is a pipe and then also close it via dup2 to /dev/null and that stops the hanging, but not sure that's the nicest way to work around that - let alone if it's worth to put a workaround into wl-copy for probably just emacs?

I guess the better way is to just use an async process in emacs so the long-living fork of wl-copy won't block emacs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants