Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wl-copy seems to be mishandling stderr #245

Open
nazarewk opened this issue Nov 28, 2024 · 6 comments
Open

wl-copy seems to be mishandling stderr #245

nazarewk opened this issue Nov 28, 2024 · 6 comments

Comments

@nazarewk
Copy link

Seems like wl-copy is doing something wrong with stderr/logging handling.

I am trying to write a clipboard anonymization script that should go like:

notify-send --expire-time=3000 "kdn-anonymize-clipboard" "$( { wl-paste | kdn-anonymize | wl-copy ; } 2>&1 )"

Initially I thought I don't understand bash process substitution and/or redirection, but after a few attempts of solving it over the months I pinned it down to wl-copy mishandling stderr in some way.

Basically above snippet results in the script hanging up indefinitely unless I augment the wl-copy call with 2>/dev/null (or any other file like 2>/tmp/wl-copy.stderr).

For minimal reproducible examples, this is working:

bash -c 'val="$( { cat -n ; echo "test stderr" >&2; } 2>&1 < <(echo "test input") > >( wl-copy 2>/tmp/wl-copy.stderr ) )"; printf "val=%s\n" "$val"'

while this is not:

bash -c 'val="$( { cat -n ; echo "test stderr" >&2; } 2>&1 < <(echo "test input") > >( wl-copy ) )"; printf "val=%s\n" "$val"'

This might be related to following:

@nazarewk nazarewk changed the title wl-copy mishandling stderr wl-copy seems to be mishandling stderr Nov 28, 2024
nazarewk added a commit to nazarewk-iac/nix-configs that referenced this issue Nov 28, 2024
@bugaevc
Copy link
Owner

bugaevc commented Nov 29, 2024

Hi!

Initially I thought I don't understand bash process substitution and/or redirection, but after a few attempts of solving it over the months I pinned it down to wl-copy mishandling stderr in some way.

Perhaps you could clarify what you mean by "mishandling" in this context?

You're probably unhappy about the forked instance of wl-copy keeping stderr instead of closing it.

$( { wl-paste | kdn-anonymize | wl-copy ; } 2>&1 )

Basically above snippet results in the script hanging up indefinitely

Well, yes, if you pass the stdout pipe as stderr too (which is what 2>&1 does) and then wait for all the copies of writing end of the pipe to be closed (which is what $(...) does), you're going to have to wait until the background wl-copy exits. So don't do that if you don't intend to wait for that. Why would you want the stderr of wl-copy to appear in notify-send's argv anyway?

@nazarewk
Copy link
Author

nazarewk commented Nov 29, 2024

You're probably unhappy about the forked instance of wl-copy keeping stderr instead of closing it.

Your explanation makes sense. I would expect:

  • wl-paste to exit closing it's FDs
  • kdn-anonymize sees stdin closed, so it closes it's stdout (wl-copy's stdin)
  • wl-copy sees stdin closed, cleans up it's FDs and exits.

Is there a particular reason why stderr is kept open?

Why would you want the stderr of wl-copy to appear in notify-send's argv anyway?

  1. I basically didn't think (nor now want) to treat wl-paste any different way than the rest of the pipeline.
  2. To for example observe messages like improperly detecting a closed wayland socket? #201 when I misconfigure something else.

@bugaevc
Copy link
Owner

bugaevc commented Nov 29, 2024

  • wl-copy sees stdin closed, cleans up it's FDs and exits.

Is there a particular reason why stderr is kept open?

We keep stderr open to be able to report errors, if any. Though it's possible that I will change my mind about this, given the never-ending torrent of issues that people file about it 🙂

wl-copy doesn't fully exit once its stdin is closed. If it did, you would be unable to paste. It needs to stay alive to service paste requests. You may want to explicitly run wl-copy --foreground for clarity.

@nazarewk
Copy link
Author

wl-copy doesn't fully exit once its stdin is closed. If it did, you would be unable to paste. It needs to stay alive to service paste requests. You may want to explicitly run wl-copy --foreground for clarity.

oh, I was under the impression the clipboard is stored in a system session or something like that instead of within wl-copy memory

@samuelmarquis
Copy link

samuelmarquis commented Dec 22, 2024

Why does the process need to stick around after stdin gets closed & the child process is joined(?)? This is perhaps naive, but could it use a file in /tmp or something instead?

@DarkArc
Copy link

DarkArc commented Feb 14, 2025

wl-copy doesn't fully exit once its stdin is closed. If it did, you would be unable to paste. It needs to stay alive to service paste requests. You may want to explicitly run wl-copy --foreground for clarity.

So I wondered if it was the forking, which eventually led me here.

I was trying to get write a simple kakoune wl-copy integration: https://stackoverflow.com/questions/41396835/how-do-i-yank-to-system-clipboard-in-kakoune

When I saw this answer, I was like "what in the world why is the wl-copy example so much more complicated, who cares about stdout/stderr and forking":

hook global RegisterModified '"' %{ nop %sh{
    case $(uname) in
        Linux)
            wl-copy -n "$kak_main_reg_dquote" > /dev/null 2>&1 & ;; 
        Darwin)
            printf "%s" "$kak_main_reg_dquote" | pbcopy ;;
        esac
}}

After trial and error, I believe this should be the correct line:

wl-copy --foreground -- "$kak_main_reg_dquote"

however, adding --foreground actually makes things worse. If I add --foreground (even if I redirect stdout and stderr to /dev/null and set stdin to /dev/null) wl-copy never exits.

This seems to be the correct incantation:

wl-copy -- "$kak_main_reg_dquote" 2> /dev/null

... this is excessively weird. Please don't keep this behavior. If there's no possibility of further input (i.e., stdin is a closed pipe or a non-pipe file descriptor that has hit EOF, or was never provided) ... I do not see why wl-copy should ever hang around.

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

No branches or pull requests

4 participants