redirect stdin/out/err to socket

Till Straumann strauman at slac.stanford.edu
Thu Oct 11 00:28:56 UTC 2007


Hmm.

AFAIK, typical UNIX code is different in so far as
it usually redirects the file descriptors 0,1,2 relying
on 'dup' or 'open' returning the smallest fd available.

On RTEMS this is not useful as fds are 'per-process'
entities. I.e., fds 0..2 point to the same underlying
file or device for all threads so you can't e.g.,
close(0); close(1); close(2); socket(); dup(); dup();
with the intent of doing stdio on the socket.
This would have implications on all threads
(and 'dup' on the RTEMS socket wouldn't work)

newlib (at least up to 1.15) has funny semantics as
far as the stdio streams (FILE objects) are concerned:
Ordinary FILE objects (ones that you create with fopen etc.)
are global objects but each newlib thread has it's own
stdin/stdout/stderr FILEs which are attached to the
thread's 'reent' struct. All other FILEs are attached to
the global 'reent' struct.
Note that each thread also has it's own stdin/out/err
pointers (AFAIK, this is not mandated by the 1003.1c
standard but is a newlib peculiarity) -- this allows us
to redirect them in the way done by telnetd.

Finally, note that telnetd does not redirect stdin/out/err
to a socket but to a device ("/dev/ptyXX") which means
that we can repeatedly call 'fopen()' to create FILE streams
and 'fclose()' to clean them.
(works ok because the pty is a termios device and the
termios driver implements nested open/close)

This probably wouldn't work on a socket since although
you can create streams using 'fdopen()' there seems to
be no way to destroy them cleanly as the first 'fclose' already
would close the underlying socket.

So the closest you could get would be (DISCLAIMER: I have
not tested this nor studied carefully!!)

   FILE *f_orig[3];

   fileno(stdout); /* make sure this thread's stdio is initialized */

   /* remember original streams */
   f_orig[0] = stdin; f_orig[1] = stdout; f_orig[2] = stderr;

   /* redirect; note that we cannot have a separate FILE on stderr nor
    * different buffering on the three streams
    */
   if ( (stderr= stdout = stdin = fdopen(socket_fd, "r+") ) {

  
       call_code_with_redirected_stdio();

       /* cleanup */
       fclose(stdout);
   } else {
       /* Handle fdopen failure */
   }

   /* restore originals; to be cleaned up by libc thread wrapper */
   stdin = f_orig[0]; stdout = f_orig[1]; stderr = f_orig[2];

HTH
-- Till

Joel Sherrill wrote:
> Hi,
>
> I was trying to understand some of the magic in telnetd
> where it redirects stdin/out/err to the socket. I have
> created a simple echoServer on UNIX and am trying to use
> the code in telnetd as reference for how to redirect
> stdio to the socket.
>
> Unfortunately, I can't reproduce the effect on GNU/Linux
> since the telnetd code uses RTEMS specific code to allocate
> the pty and redirect.
>
> Can someone point me to some example code that does this
> on UNIX?
>
> Just wanting to learn. :-D
>
> --joel
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users
>   





More information about the users mailing list