public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Jun T <takimoto-j@kba.biglobe.ne.jp>
To: cygwin@cygwin.com
Subject: killpg(pgid, 0) fails if the process is in the middle of spawnve()
Date: Wed, 18 May 2022 20:19:31 +0900	[thread overview]
Message-ID: <08B78336-7554-4ACA-80EF-F87C3C04C781@kba.biglobe.ne.jp> (raw)

Dear Cygwin developers,

It seems killpg(2) on Cygwin has a problem as described below.
Can this be (easily) fixed?

[1] The problem

killpg(pgid, 0) (or kill_pgrp(pgid, si_signo=0), in signal.cc)
fails (returns -1) even when there is a process in the process
group pgid, if the process is in the middle of spawnve().

[2] A problem of zsh on Cygwin that is caused by [1]

More than a year ago, a user of zsh on Cygwin/MSYS2 reported
to the zsh/workers mailing list:
https://www.zsh.org/mla/workers/2021/msg00060.html

As described in this post, it can sometimes (or frequently)
happen that a pipeline like 'ls | less' results in:

zsh% ls --color | less
zsh: done                    ls --color |
zsh: suspended (tty output)  less

How frequently you get this may depend on your hardware,
but if it happens you will find it quite annoying.

[3] How does [1] cause [2]?

According to the strace output, what is happening is as follows:

The main zsh (zsh0) fork() two subshells, zsh1 for ls and
zsh2 for less.
zsh1 becomes a process group leader (pid=pgid=101, for example),
gets tty (becomes foreground), and calls execve(ls).
zsh2 becomes a member of the process group pgid=101, and
calls execve(less).

When ls exits, zsh0 gets SIGCHLD, and in the signal handler
it calls killpg(101, 0) to see if there are any process
remaining in the process group 101. At this point zsh2/less
is still in the process group 101, so killpg(101, 0) should
succeed.

But when problem [2] happens, zsh2 has already called execve(less)
or spawnve(_P_OVERLAY,less), but spawnve() has not finished yet.

There are two Windows processes (zsh2 and less), but it _seems_
neither of them is included in the list of win-pids created by
    winpids pids ((DWORD) PID_MAP_RW);
at line 358 of signal.cc. So kill_pgrp() fails, and zsh0 thinks
that there is no foreground process remaining, and regains tty.

Later spawnve(less) completes, and less wants to write to stdout,
but it has not tty, and is stopped by SIGTTOU.

Is it possible to fix the problem [1], so that killpg(pgid, 0)
succeeds even when all the process(es) in the process group pgid
is/are in the middle of spawnve()?

--
Jun

             reply	other threads:[~2022-05-18 11:19 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-18 11:19 Jun T [this message]
2022-05-18 14:54 ` Corinna Vinschen
2022-05-19  4:51   ` Jun T
2022-05-19  7:46     ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=08B78336-7554-4ACA-80EF-F87C3C04C781@kba.biglobe.ne.jp \
    --to=takimoto-j@kba.biglobe.ne.jp \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).