From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Shawn Presser Newsgroups: gmane.emacs.bugs Subject: bug#34123: A patch to fix reading EOF characters in non-interactive mode Date: Fri, 18 Jan 2019 08:22:31 -0600 Message-ID: References: <8336pqcd3l.fsf@gnu.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="00000000000020dca5057fbc3bdd" X-Trace: blaine.gmane.org 1547821216 12952 195.159.176.226 (18 Jan 2019 14:20:16 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 18 Jan 2019 14:20:16 +0000 (UTC) Cc: 34123@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Jan 18 15:20:12 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gkV0G-0003Go-80 for geb-bug-gnu-emacs@m.gmane.org; Fri, 18 Jan 2019 15:20:12 +0100 Original-Received: from localhost ([127.0.0.1]:40353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkV2N-0001rn-8c for geb-bug-gnu-emacs@m.gmane.org; Fri, 18 Jan 2019 09:22:23 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:33815) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gkV24-0001mQ-TA for bug-gnu-emacs@gnu.org; Fri, 18 Jan 2019 09:22:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gkV23-0007t9-23 for bug-gnu-emacs@gnu.org; Fri, 18 Jan 2019 09:22:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:36542) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gkV22-0007rO-Cc for bug-gnu-emacs@gnu.org; Fri, 18 Jan 2019 09:22:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gkV22-0005eM-1z for bug-gnu-emacs@gnu.org; Fri, 18 Jan 2019 09:22:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Shawn Presser Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 18 Jan 2019 14:22:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 34123 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 34123-submit@debbugs.gnu.org id=B34123.154782131421704 (code B ref 34123); Fri, 18 Jan 2019 14:22:02 +0000 Original-Received: (at 34123) by debbugs.gnu.org; 18 Jan 2019 14:21:54 +0000 Original-Received: from localhost ([127.0.0.1]:35823 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gkV1u-0005e0-3r for submit@debbugs.gnu.org; Fri, 18 Jan 2019 09:21:54 -0500 Original-Received: from mail-ot1-f50.google.com ([209.85.210.50]:36013) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gkV1s-0005dn-0Y for 34123@debbugs.gnu.org; Fri, 18 Jan 2019 09:21:52 -0500 Original-Received: by mail-ot1-f50.google.com with SMTP id k98so14505274otk.3 for <34123@debbugs.gnu.org>; Fri, 18 Jan 2019 06:21:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=QaV+hq2x1BEfqZ7mOI9CjrmKiK+6rx/06P3GIJPeI08=; b=OGB++7UXY9QJoPZUX+FbgbNmVKcJpZhby7MedJMYcMGs/4kvzLCsHSQrmeNrW1chpX 72Hr4OscYkkC/deX0mvQ4d1iZwhCE+8TnlVjcBsu+VyxVM4sAVqY/Hp+EyBk2YhauqlI Fa08+GjASicl0pkYDsPWFf9lKld6cSLnSnOcHM6sRULT1B0p/YKc2j6qquF8x6XxnJmr E1ZKQYQl+oHRWoJVIPPOuVPGFynCn0Bo0V3IAA8dTkCW3+oUd/YuZghL6h3wFnBZw+3H 139D3ZpCFnRUXRm8YC3uWZKNI9FEO5LG1Hh3qMaFI/0CLz1i9MiI4TYHiXNOD8LM+cL+ JwaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=QaV+hq2x1BEfqZ7mOI9CjrmKiK+6rx/06P3GIJPeI08=; b=SehCRqnvmmfMCyboO/ZhsRUD6c7Wkw73lvi1llFuySyqWkbII25NTXHAXtM8I6UyEO zMoaqShXrwwnTliGIOyUBAlFFHKDHb/ibb9ezJ9F8XAzfJlPkvMyakNPffiN4vOoxCwK VZO11awDe33vFjYBVr7xXWeuVFfWHDU8aHB5xwp5f38UwEPLbtQqWzCk5Rb/sR6MHeTt NF+sGGMR7YjoXuFFIcsFIkz41SDGTurz3aCDUZBxyfBJg9sMxTxtAoOyK6hOnxA9n8Kj mqgnep6JKJGxZ5wFtRmNQk+mzCuBOMXfmdkkmhHe0/ZIyon1XY0dCDrEMmf3bOWUMArq eoLg== X-Gm-Message-State: AJcUukeBa+W05mEMhV5SUVdEVimjcZ3pRIVQ4vvqfg2V7451HmpN9wGS ViFnSRZzrmbh2oAva/yTIo89kPm4aTRe5Xuck4o= X-Google-Smtp-Source: ALg8bN7XhJq3p06DrvllBDcGfbK1WRHICRR8nADNuwMpbayh609WUHGrHm8uGjVqVQxbNjxoZuHRLzl5rwCH62OAAKU= X-Received: by 2002:a9d:32c7:: with SMTP id u65mr11538520otb.236.1547821306140; Fri, 18 Jan 2019 06:21:46 -0800 (PST) In-Reply-To: <8336pqcd3l.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:154550 Archived-At: --00000000000020dca5057fbc3bdd Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable I use Emacs Lisp as a runtime for Arc (https://github.com/shawwn/arcmacs) a= nd for Lumen (https://github.com/shawwn/y). The goal is to be able to run a Lisp REPL from the terminal. For example, in Arc: $ git clone https://github.com/laarc/laarc $ cd laarc $ make $ bin/arc Use (quit) to quit, (tl) to return here after an interrupt. arc> 1 1 arc> (def my-repl () (pr "> ") (whilet expr (read) (write (eval expr)) (prn) (pr "> "))) *** redefining repl # arc> (my-repl) > 1 ; we can exit this inner REPL with control-D, without exiting the program. 1 > (+ 1 2) 3 > ^D arc> "If this were emacs in batch mode, the program would have exited with errors here." "If this were emacs in batch mode, the program would have exited with errors here." arc> "Instead, control-D returned us to the toplevel REPL. Let's type another control-D to quit." "Instead, control-D returned us to the toplevel REPL. Let's type another control-D to quit." arc> ^D $ Please compare this with arcmacs, which runs in Emacs Lisp: $ git clone https://github.com/shawwn/arcmacs $ cd arcmacs $ ./y-arc Use (quit) to quit, (tl) to return here after an interrupt. arc> 1 1 arc> (def my-repl () (pr "> ") (whilet expr (read) (write (eval expr)) (prn) (pr "> "))) arc> (my-repl) > 1 ; if we enter control-D, every REPL exits immediately and the program quits 1 > 2 2 > ^D arc> $ echo We didn't intend to quit yet! A single ^D exits the entire program, not just the inner REPL. This is because after the user enters control-D, any attempt to call `read-from-minibuffer` will always result in emacs throwing an error with the message "Error reading from stdin". The only way to gracefully handle this case in a script is to trap the internal emacs error with (ignore-errors (read-from-minibuffer "")) and to treat a nil result as if it were EOF. But that causes every nested REPL to exit, since every attempt to (read-from-minibuffer "") will throw "Error reading from stdin". In other words, emacs is always failing to read from stdin after the user sends an EOF. This patch fixes the problem by causing (read-from-minibuffer "") to return nil if the user types control-D. On Fri, Jan 18, 2019 at 7:25 AM Eli Zaretskii wrote: > > From: Shawn Presser > > Date: Fri, 18 Jan 2019 04:35:34 -0600 > > > > $ git clone https://github.com/shawwn/y > > $ cd y > > $ bin/y > > > (read t) > > Lisp expression: 42 > > 42 > > > (read t) > > Lisp expression: ^Derror: Error reading from stdin > > > Error reading from stdin > > $ > > > > Notice that it=E2=80=99s currently impossible for non-interactive scrip= ts to > recover from EOF when reading from tty. > > What would you want such non-interactive scripts to do after recovery? > --00000000000020dca5057fbc3bdd Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I use Emacs Lisp as a runtime for Arc (https://github.com/shawwn/arcmacs)=C2=A0and for Lum= en (https://github.com/shawwn/y= ). The goal is to be able to run a Lisp REPL from the terminal.

For example, in Arc:

=C2=A0 $ cd laarc
=C2=A0 $ make
=C2=A0 $ bin/arc
=C2=A0 Use (quit) to quit, (tl) to return here after a= n interrupt.
=C2=A0 ar= c> 1
=C2=A0 1
=C2=A0 arc> (def my-repl= ()
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(pr "> ")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(whilet expr (read)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0(write (eval expr))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(prn) (pr ">= ; ")))
=C2=A0 ***= redefining repl
=C2= =A0 #<procedure: repl>
=C2=A0 arc> (my-repl)
=C2=A0 > 1=C2=A0; we can exit this inner REPL with control-D, without exiting the = program.
=C2=A0 1
=C2=A0 > (+ 1 2)=
=C2=A0 3
=C2=A0 > ^D
=C2=A0 arc> "If this were emacs in batch= mode, the program would have exited with errors here."
=C2=A0 "If this were emacs in b= atch mode, the program would have exited with errors here."
=C2=A0 arc> "Instead, co= ntrol-D returned us to the toplevel REPL. Let's type another control-D = to quit."
=C2=A0 = "Instead, control-D returned us to the toplevel REPL. Let's type a= nother control-D to quit."
=C2=A0 arc> ^D
=C2=A0 $

Please compare this wi= th arcmacs, which runs in Emacs Lisp:

<= font face=3D"monospace, monospace">=C2=A0 $ cd arcmacs
=C2=A0 $ ./y-arc
=C2=A0 Use (quit) to quit, (tl) to return here = after an interrupt.
= =C2=A0 arc> 1
=C2= =A0 1
=C2=A0 arc> (= def my-repl ()
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(pr "> ")
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(whilet expr = (read)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(write (eval expr))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(prn) (p= r "> ")))
=C2=A0 arc> (my-repl)
=C2=A0 > 1=C2=A0=C2=A0; if we ent= er control-D, every REPL exits immediately and the program quits
=C2=A0 1
=C2=A0 > 2
=C2=A0 2
=C2=A0 > ^D
=C2=A0 $ echo=C2=A0= We didn't intend to quit yet!

A single = ^D exits the entire program, not just the inner REPL. This is
bec= ause after the user enters control-D, any attempt to call
`read-f= rom-minibuffer` will always result in emacs throwing an error
wit= h the message "Error reading from stdin".

The only way to gracefully handle this case in a script is to trap the
internal emacs error with (ignore-errors (read-from-minibuffer &quo= t;"))
and to treat a nil result as if it were EOF. But that = causes every
nested REPL to exit, since every attempt to (read-fr= om-minibuffer "")
will throw "Error reading from s= tdin". In other words, emacs is
always failing to read from = stdin after the user sends an EOF.

This patch fixe= s the problem by causing (read-from-minibuffer "") to
r= eturn nil if the user types control-D.


On Fri, Jan 18, 2019 at 7:25 AM Eli Zaretskii <eliz@gnu.org> wrote:
> From: Shawn Presser <shawnpresser@gmail.com>
> Date: Fri, 18 Jan 2019 04:35:34 -0600
>
> $ git clone https://github.com/shawwn/y
> $ cd y
> $ bin/y
> > (read t)
> Lisp expression: 42
> 42
> > (read t)
> Lisp expression: ^Derror: Error reading from stdin
> > Error reading from stdin
> $
>
> Notice that it=E2=80=99s currently impossible for non-interactive scri= pts to recover from EOF when reading from tty.

What would you want such non-interactive scripts to do after recovery?
--00000000000020dca5057fbc3bdd--