Article View: gnu.emacs.bug
Article #98877wait_reading_process_input () is not reentrant
From: Yutaka Niibe
Date: Fri, 25 Jan 1991 05:22
Date: Fri, 25 Jan 1991 05:22
156 lines
5578 bytes
5578 bytes
In GNU Emacs 18.55.5 of Thu Jan 24 1991 on naga.ee.uec.ac.jp (berkeley-unix)
This is BUG report.
Here we go.
* The function wait_reading_process_input () is not reentrant
The function wait_reading_process_input () (in process.c) is not
reentrant. So, it may kill alive process wrongly. It goes like:
(1) First, wait_reading_process_input () is called.
(2) Doing system call select (), variable Available is set to
indicate which channels of outputs from processes are available.
(3) Suppose, two channels are available and process of first channel
has filter function which may call function like `sit-for',
`sleep-for', `accept-process-output', or `read-char'.
(4) It reads outputs from first channel, and call the filter
function.
(5) The filter function call `read-char' and
wait_reading_process_input () is REENTERD.
(6) Second wait_reading_process_input () does system call select (),
and find second channel available.
(7) Second wait_reading_process_input () reads from second channel,
and works with it, and finally returns.
(8) Now, we are in first wait_reading_process_input ().
(9) First wait_reading_process_input () trys to read from second
channel, but it find there is no data.
(10) It thinks process of second channel has exited, and kills
connection. Oh unhappy second process!
* Example that generate wrong action
Here is example lisp expression that generate wrong action.
Please evaluate.
(let* ((i 0)
(cat1 (start-process "cat1" nil "cat" "-"))
(cat2 (start-process "cat2" nil "cat" "-"))
)
(set-process-filter cat1 '(lambda (proc str)
(message (substring str 0 -1))
(sit-for 1)))
(set-process-filter cat2 '(lambda (proc str)
(ding)))
(while (< i 10)
(process-send-string cat1 (format "%d\n" i))
(process-send-string cat2 "\n")
(sleep-for 1)
(setq i (1+ i)))
(delete-process cat1)
(delete-process cat2))
Expected action is showing message in echo area and dinging
10 time one after another.
But it stops with error `Process cat2 not running' because of
existence of `sit-for' in cat1's filter.
If you change order of starting processes like following example,
it works fine.
(let* ((i 0)
(cat2 (start-process "cat2" nil "cat" "-"))
(cat1 (start-process "cat1" nil "cat" "-"))
)
...
* What's my warrant for saying it is `BUG'?
(1) GNU Emacs Lisp Reference Mannual (edition 1.02) says
(pp.480, 32.8.2 Process Filter Functions):
A filter function must accept two arguments: the associated process
and a string, which is the output. The function is then free to do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
whatever it chooses to with the output.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(I added ^^.)
(2) There exist applications using filter that may invoke
wait_reading_process_input ().
Following list shows such applications I examined.
In directory dist-18.55/lisp/:
server.el
server-process-filter --> server-visit-files --> y-or-n-p
telnet.el
telnet-initial-filter --> read-password --> read-char
xscheme.el
xscheme-process-filter --> xscheme-prompt-for-confirmation --> y-or-n-p
(funcall)
and in another directory:
ange-ftp.el
ange-ftp-gwp-filter --> ange-ftp-get-passwd --> read-char
--> ange-ftp-get-user --> read-string
* Patch
I add my proposal patch at the end of this bug report. Only 7
characters are inserted. I make the variable `Available' to be
`static'. So, the function wait_reading_process_input () becomes
reentrant.
I think this solution is right. Emacs works well with this patch, at
least my environment.
***
Finally, I want to express my special thanks to Richard M. Stallman
and FSF. I love GNU Emacs very much.
Thanks.
Yutaka NIIBE
Department of Electronic Engineering
The University of Electro-Communications, Tokyo, Japan.
e-mail: niibe@naga.ee.uec.ac.jp <-- valid until APRIL
=== patch goes from here ====
In case of emacs-18.55, output will be:
Hunk #1 succeeded at 1289 (offset -70 lines).
In case of Nemacs-3.3.2, output will be:
Hunk #1 succeeded at 1351 (offset -8 lines).
*** process.c~ Sat Jan 19 19:09:51 1991
--- process.c Thu Jan 24 10:48:33 1991
***************
*** 1359,1365 ****
int time_limit, read_kbd, do_display;
{
register int channel, nfds, m;
! int Available = 0;
int Exception;
int xerrno;
Lisp_Object proc;
--- 1359,1365 ----
int time_limit, read_kbd, do_display;
{
register int channel, nfds, m;
! static int Available = 0;
int Exception;
int xerrno;
Lisp_Object proc;
=== end of patch ====
Technical Details
Message-ID:
<9101250522.AA07749@naga.ee.uec.ac.jp>Path:
arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!naga.ee.uec.ac.jp!ytkShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fb2f1,9abd62cf39e1b33,start X-Google-Attributes: gidfb2f1,public X-Google-ArrivalTime: 1991-01-24 21:22:10 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!naga.ee.uec.ac.jp!ytk From: ytk@naga.ee.uec.ac.jp (Yutaka Niibe) Newsgroups: gnu.emacs.bug Subject: wait_reading_process_input () is not reentrant Message-ID: <9101250522.AA07749@naga.ee.uec.ac.jp> Date: 25 Jan 91 05:22:10 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 156 Approved: bug-gnu-emacs@prep.ai.mit.edu