From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Jim Porter Newsgroups: gmane.emacs.bugs Subject: bug#54062: 29.0.50; [PATCH] Eshell should inform processes when a pipe is broken Date: Sat, 19 Feb 2022 13:18:16 -0800 Message-ID: References: <7da3e8b2-7400-dca6-6d92-0a60e3d9c215@gmail.com> <83mtinz222.fsf@gnu.org> <83ley6y5gx.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="13342"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 54062@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Feb 19 22:19:12 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nLX8J-0003HF-LZ for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 19 Feb 2022 22:19:11 +0100 Original-Received: from localhost ([::1]:35396 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nLX8H-0001Nm-Qp for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 19 Feb 2022 16:19:09 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:55188) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nLX8A-0001Nc-UK for bug-gnu-emacs@gnu.org; Sat, 19 Feb 2022 16:19:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:36700) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nLX8A-0002so-L6 for bug-gnu-emacs@gnu.org; Sat, 19 Feb 2022 16:19:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nLX8A-0000gM-CB for bug-gnu-emacs@gnu.org; Sat, 19 Feb 2022 16:19:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Jim Porter Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 19 Feb 2022 21:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 54062 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 54062-submit@debbugs.gnu.org id=B54062.16453055052575 (code B ref 54062); Sat, 19 Feb 2022 21:19:02 +0000 Original-Received: (at 54062) by debbugs.gnu.org; 19 Feb 2022 21:18:25 +0000 Original-Received: from localhost ([127.0.0.1]:58829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nLX7Z-0000fR-3R for submit@debbugs.gnu.org; Sat, 19 Feb 2022 16:18:25 -0500 Original-Received: from mail-pg1-f172.google.com ([209.85.215.172]:36649) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nLX7X-0000fE-7z for 54062@debbugs.gnu.org; Sat, 19 Feb 2022 16:18:23 -0500 Original-Received: by mail-pg1-f172.google.com with SMTP id h125so10866263pgc.3 for <54062@debbugs.gnu.org>; Sat, 19 Feb 2022 13:18:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:cc:references:from:message-id:date:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=TFJQ3jQaKnQaosNHg9zdyH3eGlBOxNUhAiZik4TdUeQ=; b=lCWXhJBUwKuqvygw9Ytr2x8Y69+6WAdNppzDSxIVzxXcRxhvZnWzY1J48g/ZcCLBdP rFxiwwKFvRtTLHtOK7iSyQSegL9VoTTuF7gkYDXkoMp+ishd9+H07l5QYXhULCjlZBpj gxlfDsJlgQdx8tJe8XzxSsIHHGqb4LnUFk2Pt8bqPG41wv2pu4yjqwK2tf8Wc16hhz7+ aLwlNZQn7ePeVztjjRQXutcJBb7GxioGDtpEu0Y0IFgQuyO9XvOpC2h+HtcxVYfN1VUZ McuHJhC9yyAK7AP6Np9apX/LDbQXAQeofLOGm9TqZomFx6UVLmQrYlOXVHMNOEDtK1hT 0p/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=TFJQ3jQaKnQaosNHg9zdyH3eGlBOxNUhAiZik4TdUeQ=; b=KXwdEjLZQvRo5N7q6IZZrqg26NVj9678VMjJ+E34LLXykSeIE9SlCJhdWI/6T6+9zQ cRW/uvqZdxbSp6Hfk+S1WYC6oG7P2qW1S8FkhvJWIJ5JwkrabAE24JYnHMgRvD9PoeTN ZRS0pntYX2Rh3/ZjDRn2uV2QeGjb73eFcmE1BRkeWUYZ2gOnI5rJJ9RzH2rmYDo+tIPB HE6Gx+XVhQe/GA1+LxLYSb2gMpKTO+VrtHOkQDgHapkyhiszwz+h9N2XHM7OHEE1RozQ d3t/FkBum/jy9kDYhAL5tYB2+VDbBK8ILW8bFJxd2CcXGJQ7i0h3SydrzP9aAD0aMjjO qifg== X-Gm-Message-State: AOAM530S71YPP41Qhc6hXsA9iIZ+8wv9VK1sJjS8KefGOA4Hs0Ii1j86 5fKdV+rPHUP6vHxuvf02R2STfaxPQkQ= X-Google-Smtp-Source: ABdhPJyjrUCgEI7weKEJvEF12Zcnrxx4nZud0kkayLlDFIH81LhxGhv+vJVWp+BiQPNIzKxyumAZvg== X-Received: by 2002:a05:6a00:1995:b0:4e1:a7dd:96d6 with SMTP id d21-20020a056a00199500b004e1a7dd96d6mr13400126pfl.16.1645305497232; Sat, 19 Feb 2022 13:18:17 -0800 (PST) Original-Received: from [192.168.1.2] (cpe-76-168-148-233.socal.res.rr.com. [76.168.148.233]) by smtp.googlemail.com with ESMTPSA id y191sm7831564pfb.78.2022.02.19.13.18.16 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 19 Feb 2022 13:18:16 -0800 (PST) In-Reply-To: <83ley6y5gx.fsf@gnu.org> Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:227207 Archived-At: On 2/19/2022 12:19 PM, Eli Zaretskii wrote: >> Cc: 54062@debbugs.gnu.org >> From: Jim Porter >> Date: Sat, 19 Feb 2022 12:02:45 -0800 >> >> One option would be to call `interrupt-process' instead, since that >> works in all cases I'm aware of. This isn't quite as nice as sending >> SIGPIPE (or equivalent) to let the process handle it how it wants, but >> at least `interrupt-process' has the same default behavior as SIGPIPE >> (i.e. terminate the process). > > Many console programs catch SIGINT, though. > > Can't we terminate ("kill") the process instead? Or maybe deleting > the process object is enough? That might work; it would definitely be better than `interrupt-process'. On the other hand, I think it would be nice to handle this case by breaking the pipe if possible, since that would be closer to how it works in regular shells, as I understand it. >> Another way would be to add a function like `process-break-pipe' (it >> could probably use a better name) that would close the read end of the >> process's output pipe, which - if I understand the Win32 API here - >> should trigger the right behavior on MS Windows too. > > You mean, delete the process object? That's how we close our end of > the pipe, no? Do you mean using `delete-process'? That works differently from how I'm imagining things. From reading the code, `delete-process' sends SIGKILL to the process group, but that means that a process that wants to do something special in response to SIGPIPE (or EPIPE, or ERROR_BROKEN_PIPE on Win32) wouldn't be able to, since that's not the signal/error it receives. In my patch, `process-break-pipe' just closes the file descriptor for the read end of the process's stdout pipe, but otherwise doesn't do anything to the process. Then, when the process tries to write to stdout again, the OS will report (via a signal and/or an error code) that the pipe is broken. Since Win32's WriteFile[1] API returns ERROR_BROKEN_PIPE in this case, that would let MS Windows programs detect and respond to broken pipes in the usual way for that platform. >> One caveat is that the head process (`yes' in the example), would only >> see the "broken pipe" error on the *next* write after the one where >> Eshell detected the broken pipe. That's easy enough to fix for cases >> where we can signal SIGPIPE directly, but it's probably ok in general >> too: after all, processes don't generally know exactly when a SIGPIPE >> might occur, so it occurring slightly later shouldn't cause problems. > > I don't see a problem here. AFAIU, closing a pipe doesn't always > deliver SIGPIPE, it can instead fail the write with EPIPE. So SIGPIPE > is not guaranteed anyway. Agreed, I don't think this is really a problem. I just wanted to note that the behavior is slightly different from how someone might expect it to work in a regular shell. (In any case, I think SIGPIPE and EPIPE occur at effectively the same time, and you would check for the latter if you ignored SIGPIPE, for example.[2] Maybe this comes with some caveats or is specific to glibc though.) >> (In theory, the tail process should call `process-break-pipe' as soon as >> it closes, but in Eshell, the tail process doesn't know what's feeding >> it input, so it can't easily do this.) > > Not sure I understand: an Emacs process object always knows what's > feeding it. Emacs process objects could probably do it, but I'm not sure if Eshell's pipelines are able to without being reworked. Eshell pipelines are assembled pretty indirectly; the output of one process goes through a process-filter and into `eshell-output-object', which looks up where to send the data in `eshell-current-handles' (which in turn is let-bound so each process has its own copy). It would probably take quite a bit of work for a process to figure out what's feeding it from its process-sentinel, since that happens in a different context than where the pipeline is constructed. Maybe it's feasible, but if we agree that my caveat in the section above isn't a problem, it would probably be simpler to avoid the extra effort. [1] https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-writefile [2] https://www.gnu.org/software/libc/manual/html_node/Operation-Error-Signals.html