unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [kazu@iij.ad.jp: a bug of read-passwd]
@ 2006-07-15 17:16 Richard Stallman
  2006-07-16  3:54 ` Chong Yidong
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Stallman @ 2006-07-15 17:16 UTC (permalink / raw)


I wonder if this is a consequence of the new sit-for code.
Would someone please investigate, then ack this message?

------- Start of forwarded message -------
DKIM-Signature: a=rsa-sha1; c=relaxed/simple; d=iij.ad.jp; s=omgo0;
	t=1152939160; bh=3mhCZUjonim4IiCzzKXwlGTyEu8=; h=Received:Received:
	Date:Message-Id:To:Subject:From:X-Mailer:Mime-Version:Content-Type:
	Content-Transfer-Encoding; b=NYBNO/qQoOsroMzwkHp6O7uqWNe+Vhjlofn0m1
	CrNZrspQa6+N/HXDG3p5UepfAwt+dX1CtHd3Dxc8zuWmqePgbUq2wdLE+OFSdUW6F2W
	qN4QWThGMEPiM599VkzY8FDelF5emurJNv1Yqvyjwq1izfE39MKa6LLnB6ADVMVK4A=
Date: Sat, 15 Jul 2006 13:49:49 +0900 (JST)
To: emacs-devel@gnu.org
From: Kazu Yamamoto (=?iso-2022-jp?B?GyRCOzNLXE9CSScbKEI=?=) <kazu@iij.ad.jp>
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Subject: a bug of read-passwd
X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=failed 
	version=3.0.4

Hello,

Recent changes of Emacs introduces a new bug to read-passwd.  If
read-passwd is called a filter of an asynchronous process and the
parent code executes sit-for, the cursor goes away from the minibuffer
and we cannot input our password.

The following code can reproduce this:

(defvar my-check nil)

(defun my-filter (process string)
  (set-buffer (process-buffer process))
  (read-passwd "Password: ")
  (setq my-check nil))

(let ((pro (start-process "*sh*" (current-buffer) "/bin/sh")))
  (setq my-check t)
  (set-process-filter pro 'my-filter)
  (while my-check
    (sit-for 0.1)
    (discard-input)))

The parent code calls sit-for to synchronize with its child process.
The code above is essence of a program which I use everyday.

This code works Emacs, at least, before Jun 31 2006.

- --Kazu Yamamoto


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
------- End of forwarded message -------

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [kazu@iij.ad.jp: a bug of read-passwd]
  2006-07-15 17:16 [kazu@iij.ad.jp: a bug of read-passwd] Richard Stallman
@ 2006-07-16  3:54 ` Chong Yidong
  2006-07-19  0:49   ` Kazu Yamamoto
  0 siblings, 1 reply; 18+ messages in thread
From: Chong Yidong @ 2006-07-16  3:54 UTC (permalink / raw)
  Cc: rms, emacs-devel

> Recent changes of Emacs introduces a new bug to read-passwd.  If
> read-passwd is called a filter of an asynchronous process and the
> parent code executes sit-for, the cursor goes away from the minibuffer
> and we cannot input our password.
>
> The following code can reproduce this:
>
> (defvar my-check nil)
>
> (defun my-filter (process string)
>   (set-buffer (process-buffer process))
>   (read-passwd "Password: ")
>   (setq my-check nil))
>
> (let ((pro (start-process "*sh*" (current-buffer) "/bin/sh")))
>   (setq my-check t)
>   (set-process-filter pro 'my-filter)
>   (while my-check
>     (sit-for 0.1)
>     (discard-input)))

Does the code work if you remove the (discard-input)?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [kazu@iij.ad.jp: a bug of read-passwd]
  2006-07-16  3:54 ` Chong Yidong
@ 2006-07-19  0:49   ` Kazu Yamamoto
  2006-07-21  0:57     ` a bug of read-passwd Kazu Yamamoto
  0 siblings, 1 reply; 18+ messages in thread
From: Kazu Yamamoto @ 2006-07-19  0:49 UTC (permalink / raw)
  Cc: emacs-devel

Hello,

> > Recent changes of Emacs introduces a new bug to read-passwd.  If
> > read-passwd is called a filter of an asynchronous process and the
> > parent code executes sit-for, the cursor goes away from the minibuffer
> > and we cannot input our password.
>
> Does the code work if you remove the (discard-input)?

Yes.

I don't remember correctly but old Emacs requires (discard-input).

--Kazu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-19  0:49   ` Kazu Yamamoto
@ 2006-07-21  0:57     ` Kazu Yamamoto
  2006-07-21 19:08       ` Chong Yidong
  0 siblings, 1 reply; 18+ messages in thread
From: Kazu Yamamoto @ 2006-07-21  0:57 UTC (permalink / raw)


Hello,

> > > Recent changes of Emacs introduces a new bug to read-passwd.  If
> > > read-passwd is called a filter of an asynchronous process and the
> > > parent code executes sit-for, the cursor goes away from the minibuffer
> > > and we cannot input our password.
> >
> > Does the code work if you remove the (discard-input)?
> 
> Yes.

With the current CVS tree, this bug still exists and the answer
changed to "NO". 

--Kazu Yamamoto

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-21  0:57     ` a bug of read-passwd Kazu Yamamoto
@ 2006-07-21 19:08       ` Chong Yidong
  2006-07-21 19:33         ` Chong Yidong
  2006-07-22  4:39         ` Richard Stallman
  0 siblings, 2 replies; 18+ messages in thread
From: Chong Yidong @ 2006-07-21 19:08 UTC (permalink / raw)
  Cc: emacs-devel

Kazu Yamamoto (山本和彦) <kazu@iij.ad.jp> writes:

> Hello,
>
>> > > Recent changes of Emacs introduces a new bug to read-passwd.  If
>> > > read-passwd is called a filter of an asynchronous process and the
>> > > parent code executes sit-for, the cursor goes away from the minibuffer
>> > > and we cannot input our password.
>> >
>> > Does the code work if you remove the (discard-input)?
>> 
>> Yes.
>
> With the current CVS tree, this bug still exists and the answer
> changed to "NO". 

I can reproduce this too.  I'll look into it.  Clearly, the
read-passwd in the asynchronous filter function is interfering with
the sit-for.

BTW, probably the cleaner thing to do for your purposes is to use
`accept-process-output':

(defvar my-check nil)

(defun my-filter (process string)
  (set-buffer (process-buffer process))
  (read-passwd "Password: ")
  (setq my-check nil))

(let ((pro (start-process "*sh*" (current-buffer) "/bin/sh")))
  (setq my-check t)
  (set-process-filter pro 'my-filter)
  (accept-process-output pro)
  (kill-process pro))

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-21 19:08       ` Chong Yidong
@ 2006-07-21 19:33         ` Chong Yidong
  2006-07-24  2:24           ` Kazu Yamamoto
  2006-07-22  4:39         ` Richard Stallman
  1 sibling, 1 reply; 18+ messages in thread
From: Chong Yidong @ 2006-07-21 19:33 UTC (permalink / raw)


>> (defvar my-check nil)
>>
>> (defun my-filter (process string)
>>   (set-buffer (process-buffer process))
>>   (read-passwd "Password: ")
>>   (setq my-check nil))
>>
>> (let ((pro (start-process "*sh*" (current-buffer) "/bin/sh")))
>>   (setq my-check t)
>>   (set-process-filter pro 'my-filter)
>>   (while my-check
>>     (sit-for 0.1)
>>     (discard-input)))
>
> I can reproduce this too.  I'll look into it.

The problem here is that the new sit-for calls (read-event) to wait
for new input.  During this time, the process filter takes over, and
that calls (read-passwd).  While the filter is waiting for the
password prompt, the sit-for timer expires, which causes a throw back
to the `sit-for', spoiling the `read-passwd'.

Not sure how to handle this situation (though, as I mentioned earlier,
the proper thing to do in this situation is to run
`accept-process-output').

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-21 19:08       ` Chong Yidong
  2006-07-21 19:33         ` Chong Yidong
@ 2006-07-22  4:39         ` Richard Stallman
  2006-07-24  4:18           ` Chong Yidong
  2006-07-24  4:54           ` Chong Yidong
  1 sibling, 2 replies; 18+ messages in thread
From: Richard Stallman @ 2006-07-22  4:39 UTC (permalink / raw)
  Cc: emacs-devel

    The problem here is that the new sit-for calls (read-event) to wait
    for new input.  During this time, the process filter takes over, and
    that calls (read-passwd).  While the filter is waiting for the
    password prompt, the sit-for timer expires, which causes a throw back
    to the `sit-for', spoiling the `read-passwd'.

We would want sit-for's timer to be suspended in its operation while
the filter is running.  This should be the case for _all_ filters.  It
does not matter whether the filter does keyboard input.  If the filter
waits for process input, that too will run timers, and the same bug
can occur.

One solution is to set up a mechanism for the sit-for timer
to determine that it has been called inside a filter.
Then it needs to be able to set up for a certain function to be
called when the filter returns.

Another solution would be, don't use a timer.
read-event works by calling wait_reading_process_output.
It should be feasible to give it a new argument
which specifies a maximum time delay.

I think the latter method is cleaner.
What do you think?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-21 19:33         ` Chong Yidong
@ 2006-07-24  2:24           ` Kazu Yamamoto
  0 siblings, 0 replies; 18+ messages in thread
From: Kazu Yamamoto @ 2006-07-24  2:24 UTC (permalink / raw)


Hello,

> Not sure how to handle this situation (though, as I mentioned earlier,
> the proper thing to do in this situation is to run
> `accept-process-output').

I changed my code so that it uses accept-process-output instead of
both sit-for and discard-input. I can type my password now. But the
code was stalled after that.

--Kazu Yamamoto

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-22  4:39         ` Richard Stallman
@ 2006-07-24  4:18           ` Chong Yidong
  2006-07-24  4:54           ` Chong Yidong
  1 sibling, 0 replies; 18+ messages in thread
From: Chong Yidong @ 2006-07-24  4:18 UTC (permalink / raw)
  Cc: emacs-devel

> Another solution would be, don't use a timer.
> read-event works by calling wait_reading_process_output.
> It should be feasible to give it a new argument
> which specifies a maximum time delay.
>
> I think the latter method is cleaner.
> What do you think?

I think this is a good idea.  I'll look into implementing it.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-22  4:39         ` Richard Stallman
  2006-07-24  4:18           ` Chong Yidong
@ 2006-07-24  4:54           ` Chong Yidong
  2006-07-24 13:22             ` Stefan Monnier
  2006-07-25  3:09             ` Richard Stallman
  1 sibling, 2 replies; 18+ messages in thread
From: Chong Yidong @ 2006-07-24  4:54 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

> One solution is to set up a mechanism for the sit-for timer
> to determine that it has been called inside a filter.
> Then it needs to be able to set up for a certain function to be
> called when the filter returns.
>
> Another solution would be, don't use a timer.
> read-event works by calling wait_reading_process_output.
> It should be feasible to give it a new argument
> which specifies a maximum time delay.

OK, I looked into this.  I think that fixing read-event to give it a
new argument specifying a max delay turns out to be not simple to
implement.

(The detailed situation is this: the old sit-for called
wait_reading_process_output for a given duration, but that's
problematic since wait_reading_process_output can return due to fake
events.  The new sit-for solves this by calling read-event, which
relies on read_char, which loops calling wait_reading_process_output
with zero duration and discarding fake events [using
kbd_buffer_get_event, which does some complicated processing to figure
out if the event is fake or not].  The new sit-for interrupts this
loop using a timer.  If we want to hack read_char to accept a new arg
specifying the max delay, there would be two sets of timing code:
inside read_char, and inside wait_reading_process_output.  This is
very inelegant.)

Another possibility is to implement a `inhibit-timers' variable and
set it to t by default inside filter functions (similar to how
`inhibit-quit' is bound to t in filter functions.)  This is probably
easier to implement.  What do you think?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-24  4:54           ` Chong Yidong
@ 2006-07-24 13:22             ` Stefan Monnier
  2006-07-24 14:17               ` Chong Yidong
  2006-07-25  3:09             ` Richard Stallman
  1 sibling, 1 reply; 18+ messages in thread
From: Stefan Monnier @ 2006-07-24 13:22 UTC (permalink / raw)
  Cc: rms, emacs-devel

> Another possibility is to implement a `inhibit-timers' variable and
> set it to t by default inside filter functions (similar to how
> `inhibit-quit' is bound to t in filter functions.)  This is probably
> easier to implement.  What do you think?

I think it's a good idea, although let-binding timer-list (and
timer-idle-list) to nil might be even better since it'd still allow filter
functions to use timers.

BTW, something similar would be useful for edebug, when debugging
repeated timers.


        Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-24 13:22             ` Stefan Monnier
@ 2006-07-24 14:17               ` Chong Yidong
  2006-07-24 14:38                 ` Stefan Monnier
  0 siblings, 1 reply; 18+ messages in thread
From: Chong Yidong @ 2006-07-24 14:17 UTC (permalink / raw)
  Cc: rms, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Another possibility is to implement a `inhibit-timers' variable and
>> set it to t by default inside filter functions (similar to how
>> `inhibit-quit' is bound to t in filter functions.)  This is probably
>> easier to implement.  What do you think?
>
> I think it's a good idea, although let-binding timer-list (and
> timer-idle-list) to nil might be even better since it'd still allow filter
> functions to use timers.

Doing a let-bind is conceptually cleaner, but one can imagine a
situation in which a filter function needs access to a
previously-defined timer.  A `inhibit-timer' mechanism would allow
filter functions to manually turn the timer back on if they need to.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-24 14:17               ` Chong Yidong
@ 2006-07-24 14:38                 ` Stefan Monnier
  0 siblings, 0 replies; 18+ messages in thread
From: Stefan Monnier @ 2006-07-24 14:38 UTC (permalink / raw)
  Cc: rms, emacs-devel

>>> Another possibility is to implement a `inhibit-timers' variable and
>>> set it to t by default inside filter functions (similar to how
>>> `inhibit-quit' is bound to t in filter functions.)  This is probably
>>> easier to implement.  What do you think?
>> 
>> I think it's a good idea, although let-binding timer-list (and
>> timer-idle-list) to nil might be even better since it'd still allow filter
>> functions to use timers.

> Doing a let-bind is conceptually cleaner, but one can imagine a
> situation in which a filter function needs access to a
> previously-defined timer.  A `inhibit-timer' mechanism would allow
> filter functions to manually turn the timer back on if they need to.

Agreed.  So maybe the inhibit-timer should not be boolean, but contain a list
of inhibited timers (it'd be set just before running a filter to the list
of timers active when the filter is started).


        Stefan

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-24  4:54           ` Chong Yidong
  2006-07-24 13:22             ` Stefan Monnier
@ 2006-07-25  3:09             ` Richard Stallman
  2006-07-26 18:33               ` Chong Yidong
  1 sibling, 1 reply; 18+ messages in thread
From: Richard Stallman @ 2006-07-25  3:09 UTC (permalink / raw)
  Cc: emacs-devel

    OK, I looked into this.  I think that fixing read-event to give it a
    new argument specifying a max delay turns out to be not simple to
    implement.

I think it is not so hard.

    (The detailed situation is this: the old sit-for called
    wait_reading_process_output for a given duration, but that's
    problematic since wait_reading_process_output can return due to fake
    events.  The new sit-for solves this by calling read-event, which
    relies on read_char, which loops calling wait_reading_process_output
    with zero duration and discarding fake events [using
    kbd_buffer_get_event, which does some complicated processing to figure
    out if the event is fake or not].

It would work right if sit-for passes down to wait_reading_process_output
the fact that it has a timeout.


				       The new sit-for interrupts this
    loop using a timer.  If we want to hack read_char to accept a new arg
    specifying the max delay, there would be two sets of timing code:
    inside read_char, and inside wait_reading_process_output.

read_char needs to do arithmetic so it can recompute the remaining
timeout, in case wait_reading_process_output returned an event
which got discarded.  But this is not very hard.  Just add the
specified timeout to the current time, at the start, and subtract
the current time before each call to wait_reading_process_output.

wait_reading_process_output does this same computation in order
to call select with the proper remaining timeout.

The inelegance of this is just a matter of repeating a little code.
At the deeper level, this design is elegant because it is very safe.
So I think we should try it.

The superficial inelegance can be removed easily if
wait_reading_process_output accepted an ending time, rather than a
duration.  That way, the addition would only be done once at the
outset, and the subtraction would only have to be done when
wait_reading_process_output is about to call select.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-25  3:09             ` Richard Stallman
@ 2006-07-26 18:33               ` Chong Yidong
  2006-07-27  0:25                 ` Richard Stallman
  0 siblings, 1 reply; 18+ messages in thread
From: Chong Yidong @ 2006-07-26 18:33 UTC (permalink / raw)
  Cc: emacs-devel

> read_char needs to do arithmetic so it can recompute the remaining
> timeout, in case wait_reading_process_output returned an event
> which got discarded.  But this is not very hard.  Just add the
> specified timeout to the current time, at the start, and subtract
> the current time before each call to wait_reading_process_output.
>
> wait_reading_process_output does this same computation in order
> to call select with the proper remaining timeout.
>
> The inelegance of this is just a matter of repeating a little code.
> At the deeper level, this design is elegant because it is very safe.
> So I think we should try it.

I've checked in changes that implement this.  `read-event' and friends
now have an optional third argument that tells them how long to wait
for.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-26 18:33               ` Chong Yidong
@ 2006-07-27  0:25                 ` Richard Stallman
  2006-07-27  0:34                   ` Yidong Chong
  2006-07-28  3:39                   ` Kazu Yamamoto
  0 siblings, 2 replies; 18+ messages in thread
From: Richard Stallman @ 2006-07-27  0:25 UTC (permalink / raw)
  Cc: emacs-devel

    I've checked in changes that implement this.  `read-event' and friends
    now have an optional third argument that tells them how long to wait
    for.

Thanks.  Did it fix the bugs that had been seen?

(Don't forget to update the Lisp manual and etc/NEWS.)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-27  0:25                 ` Richard Stallman
@ 2006-07-27  0:34                   ` Yidong Chong
  2006-07-28  3:39                   ` Kazu Yamamoto
  1 sibling, 0 replies; 18+ messages in thread
From: Yidong Chong @ 2006-07-27  0:34 UTC (permalink / raw)
  Cc: emacs-devel

>    I've checked in changes that implement this.  `read-event' and friends
>    now have an optional third argument that tells them how long to wait
>    for.
>
> Thanks.  Did it fix the bugs that had been seen?

Yes.

> (Don't forget to update the Lisp manual and etc/NEWS.)

Done.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: a bug of read-passwd
  2006-07-27  0:25                 ` Richard Stallman
  2006-07-27  0:34                   ` Yidong Chong
@ 2006-07-28  3:39                   ` Kazu Yamamoto
  1 sibling, 0 replies; 18+ messages in thread
From: Kazu Yamamoto @ 2006-07-28  3:39 UTC (permalink / raw)


Hello,

>     I've checked in changes that implement this.  `read-event' and friends
>     now have an optional third argument that tells them how long to wait
>     for.
> 
> Thanks.  Did it fix the bugs that had been seen?

Yes. Thanks!

--Kazu Yamamoto

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2006-07-28  3:39 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-15 17:16 [kazu@iij.ad.jp: a bug of read-passwd] Richard Stallman
2006-07-16  3:54 ` Chong Yidong
2006-07-19  0:49   ` Kazu Yamamoto
2006-07-21  0:57     ` a bug of read-passwd Kazu Yamamoto
2006-07-21 19:08       ` Chong Yidong
2006-07-21 19:33         ` Chong Yidong
2006-07-24  2:24           ` Kazu Yamamoto
2006-07-22  4:39         ` Richard Stallman
2006-07-24  4:18           ` Chong Yidong
2006-07-24  4:54           ` Chong Yidong
2006-07-24 13:22             ` Stefan Monnier
2006-07-24 14:17               ` Chong Yidong
2006-07-24 14:38                 ` Stefan Monnier
2006-07-25  3:09             ` Richard Stallman
2006-07-26 18:33               ` Chong Yidong
2006-07-27  0:25                 ` Richard Stallman
2006-07-27  0:34                   ` Yidong Chong
2006-07-28  3:39                   ` Kazu Yamamoto

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

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).