Hi,
I've found that the infinite loop where emacs goes is in the file xterm.c:
for (count = input_signal_count + 10;
> input_signal_count < count && !FRAME_VISIBLE_P (f);)
> {
> /* Force processing of queued events. */
> x_sync (f);
>
> /* Machines that do polling rather than SIGIO have been
> observed to go into a busy-wait here. So we'll fake an
> alarm signal to let the handler know that there's something
> to be read. We used to raise a real alarm, but it seems
> that the handler isn't always enabled here. This is
> probably a bug. */
> if (input_polling_used ())
> {
> /* It could be confusing if a real alarm arrives while
> processing the fake one. Turn it off and let the
> handler reset it. */
> extern void poll_for_input_1 P_ ((void));
> int old_poll_suppress_count = poll_suppress_count;
> poll_suppress_count = 1;
> poll_for_input_1 ();
> poll_suppress_count = old_poll_suppress_count;
> }
>
> /* See if a MapNotify event has been processed. */
> FRAME_SAMPLE_VISIBILITY (f);
> }
>
Seems to be that "if (input_polling_used ())" prevents from this infinite
loop, but there is a problem with the function input_polling_used ():
It is defined in keyboard.c:
int
> input_polling_used ()
> {
> #ifdef POLL_FOR_INPUT
> /* XXX This condition was (read_socket_hook && !interrupt_input),
> but read_socket_hook is not global anymore. Let's pretend that
> it's always set. */
> return !interrupt_input;
> #else
> return 0
> #endif
> }
>
And interrupt_input depends on two things:
#ifdef INTERRUPT_INPUT
> interrupt_input = 1;
> #else
> interrupt_input = 0;
> #endif
>
in s/bsd-common.h INTERRUPT_INPUT is undefined, but in s/gnu-kfreebsd.h it
is defined, but I think the problem isn't here.
I think the problem is this:
from keyboard.c:
#ifdef SIGIO
> /* Note SIGIO has been undef'd if FIONREAD is missing. */
> #ifdef HAVE_X_WINDOWS
> if (x_display_list != NULL)
> {
> /* When using X, don't give the user a real choice,
> because we haven't implemented the mechanisms to support it. */
> #ifdef NO_SOCK_SIGIO
> new_interrupt_input = 0;
> #else /* not NO_SOCK_SIGIO */
> new_interrupt_input = 1;
> #endif /* NO_SOCK_SIGIO */
> }
> else
> #endif /* HAVE_X_WINDOWS */
> new_interrupt_input = !NILP (interrupt);
> #else /* not SIGIO */
> new_interrupt_input = 0;
> #endif /* not SIGIO */
>
> if (new_interrupt_input != interrupt_input)
> {
> #ifdef POLL_FOR_INPUT
> stop_polling ();
> #endif
> #ifndef DOS_NT
> /* this causes startup screen to be restored and messes with the
> mouse */
> reset_all_sys_modes ();
> #endif
> interrupt_input = new_interrupt_input;
> #ifndef DOS_NT
> init_all_sys_modes ();
> #endif
>
> #ifdef POLL_FOR_INPUT
> poll_suppress_count = 1;
> start_polling ();
> #endif
> }
> return Qnil;
> }
>
>
new_interrupt_input value is determined by "new_interrupt_input = !NILP
(interrupt);" , and interrupt_input is overwrited with new_interrupt_input.
So in order to break the infinite loop, new_interrupt_input value should be
0, because "input_polling_used ()" returns !interrupt_input, but
new_interrupt_input value is always 1.
In order to avoid this, we could add in s/gnu-kfreebsd.h this as a
workaround:
#define BROKEN_FIONREAD
>
because in keyboard.c:
/* Allow m- file to inhibit use of FIONREAD. */
> #ifdef BROKEN_FIONREAD
> #undef FIONREAD
> #endif
>
> /* We are unable to use interrupts if FIONREAD is not available,
> so flush SIGIO so we won't try. */
> #if !defined (FIONREAD)
> #ifdef SIGIO
> #undef SIGIO
> #endif
> #endif
>
and because "new_interrupt_input = !NILP (interrupt);" only if SIGIO is
defined.
This is a very bad solution, I think, but I have no enough knowledge to find
any better way to solve this problem.
I have tested this, and it worked for me.
Cheers!
PD:Another possibility is to fix new_interrupt_input value always to 0, only
in GNU/kFreeBSD, but I think the main problem is in "new_interrupt_input =
!NILP (interrupt);", although, I couldn't find where is NILP definition
PD2: I'm a complete newbie in this, I'm sorry if I've wrote something silly
:)