Repository navigation
Description
Problem
wl-copy backgrounds itself after acquiring the clipboard selection, but the clipboard-serving child remains in the caller's process group.
If wl-copy is launched by a foreground terminal application and that application is suspended with Ctrl-Z, the terminal sends SIGTSTP to the foreground process group. This also stops the background wl-copy process.
The clipboard selection still points to that stopped provider, so subsequent paste requests can block indefinitely.
Minimal reproduction
sh -c 'printf test | wl-copy; sleep 9999'Press Ctrl-Z, then run:
wl-pasteThe paste blocks.
The process state can be inspected with:
ps -o pid,ppid,pgid,sid,stat,tty,cmd -C wl-copy
jobs -lThe background wl-copy provider remains in the same PGID as the suspended foreground job and has a stopped (T) state.
Sending SIGCONT to the wl-copy process allows the pending paste to complete again.
Cause
The current background path redirects stdin/stdout, changes directory, ignores SIGHUP, and then forks:
pid_t pid = fork();
if (pid < 0) {
perror("fork");
}
if (pid > 0) {
exit(0);
}The forked child inherits the parent's process group, so although it is described as running "in the background", it remains part of the original terminal job for job-control purposes.
Possible fix
Would it make sense for the clipboard-serving child to enter a separate process group when --foreground is not used?
For example, the parent could put the child into its own process group before exiting:
if (pid > 0) {
if (setpgid(pid, pid) < 0) {
perror("setpgid");
}
exit(0);
}Doing this from the parent avoids a race where the original wl-copy process could exit before the child changes its own process group.
This would keep the clipboard provider in the same session while preventing terminal job-control signals directed at the caller's foreground process group from stopping it.
Using setsid() also avoids the problem, but creating a new process group seems like the smaller behavioral change.
Originally observed in
I first encountered this through OpenCode on Wayland:
Running wl-copy through setsid fixes the OpenCode reproduction.
Related issues
These discuss why wl-copy remains alive after copying, but do not appear to cover the inherited process-group / SIGTSTP behavior:
- Why does wl-copy fork and stick around? #138 — Why does wl-copy fork and stick around?
- wl-copy doesn't close #128 — wl-copy doesn't close
- How come every time
wl-copyis called, a new process is generated and then put to sleep? #82 — background wl-copy processes - wl-copy seems to be mishandling
stderr#245 — background process / file descriptor handling
Activity