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