General PTY and CONSOLE question--SOLVED
Gene Smith
gds at chartertn.net
Mon Sep 22 15:47:48 UTC 2008
Joel Sherrill wrote, On 09/22/2008 11:16 AM:
>> Joel,
>> Here is my understanding (possibly over simplified) of what is
>> happening: Yes, there are two threads here, 1) my application still
>> containing kbhit() function and 2) the standard 4.8.0 telnetd. Since I
>> have no CONSOLE driver enabled, the first socket() call returns 0 which
>> is the "des_socket" used in telnetd. This gets opened OK.
> Right. First call to open() gets fd=0.
>> Then my task
>> runs and fails on the kbhit() due to no CONSOLE driver. I call
>> rtems_panic() which eventually reaches the point where stdin (also FD 0,
>> I think) is called.
> Not exactly. rtems_panic() called exit() which closes
> stdin, out, and error
Right, right! I meant to say "where stdin is closed" not called. This
occurs in newlibc_exit.c in function libc_wrapup():
/*
* Try to drain output buffers.
*
* Should this be changed to do *all* file streams?
* _fwalk (_REENT, fclose);
*/
fclose (stdin);
fclose (stdout);
fclose (stderr);
My point is why are these closed when they were never opened? That would
avoid the problem of socket 0 failing accept() and being closed twice (I
think).
Possibly it should do something like this:
if (global_var_console_exists_and_opened)
{
fclose (stdin);
fclose (stdout);
fclose (stderr);
}
>> The chain of code realizes FD 0 is a socket and
>> closes it, freeing some memory and setting the SS_CANTRCVMORE bit in the
>> so_state for socket 0. After this, but before everything shuts down, the
>> accept() call in telnetd sees this SS_CANTRCVMORE flag and returns a -1.
>> This causes the endless loop to exit and the "des_socket" 0 is closed.
>> Since FD 0 was already closed by the _fclose(stdin) this caused the
>> malloc/free error that I see in telnetd.
>>
>>
> Sounds like the socket close code has no idea that it shouldn't
> close it a second time. Somehow we get deep in the bowels
> for a closed file descriptor. I wonder if simply calling close()
> twice on a socket fd would reproduce the problem.
>> So I think the problem is:
>> 1) socket allocation starts at 0 when there is no console driver
>> (instead of 3 when there is).
>> 2) _fclose(stdin=0) occurs when there is no console (I assume stdin was
>> never opened?)
>>
> Right. Not having /dev/console results in this. When
> /dev/console is present, the three open() calls for stdin,
> out, and error will open 0-2.
>
> I think it is just a long weird chain of things. But somehow
> the socket close code doesn't know it has already been closed.
>
>> 3) I called rtems_panic() in my user program.
>>
>> Not doing 3 fixes the situation for me.
>>
>> -gene
More information about the users
mailing list