[PATCH 2/6] telnetd: Convert pty driver to new Termios API

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Sep 26 08:30:44 UTC 2018


Update #3526.
---
 cpukit/include/rtems/pty.h |  71 ++-----
 cpukit/telnetd/pty.c       | 474 ++++++++++-----------------------------------
 cpukit/telnetd/telnetd.c   |  58 +++---
 3 files changed, 146 insertions(+), 457 deletions(-)

diff --git a/cpukit/include/rtems/pty.h b/cpukit/include/rtems/pty.h
index 392bfd0969..d8f886d76a 100644
--- a/cpukit/include/rtems/pty.h
+++ b/cpukit/include/rtems/pty.h
@@ -16,58 +16,25 @@
 extern "C" {
 #endif	
 
-#include <rtems.h>	
-
-/* Number of ptys to setup */
-extern size_t rtems_pty_maximum_ptys;
-
-/* Return the devname for a free pty slot.
- * If no slot available (socket>=0)
- * then the socket argument is closed
- */
-char * rtems_pty_get(int socket);
-
-
-/* OBSOLETE */
-#define get_pty		rtems_pty_get
-
-rtems_device_driver pty_initialize(
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor,
-  void                      *arg);
-rtems_device_driver pty_open(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg);
-rtems_device_driver pty_close(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg);
-rtems_device_driver pty_read(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg);
-rtems_device_driver pty_write(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg);
-rtems_device_driver pty_control(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg);
-
-
-#define PTY_DRIVER_TABLE_ENTRY \
-       { pty_initialize , pty_open , pty_close , \
-   pty_read , pty_write , pty_control }
-
-/* Internal functions */
-
-int telnet_pty_initialize(void);
-
-int telnet_pty_finalize(void);
-
-char *telnet_get_pty(int);
+#include <rtems/termiostypes.h>
+
+#define RTEMS_PTY_SB_MAX 16
+
+typedef struct {
+  rtems_termios_device_context  base;
+  rtems_termios_tty            *ttyp;
+  tcflag_t                      c_cflag;
+  int                           socket;
+  int                           last_cr;
+  unsigned                      iac_mode;
+  unsigned char                 sb_buf[RTEMS_PTY_SB_MAX];
+  int                           sb_ind;
+  int                           width;
+  int                           height;
+  char                          name[sizeof("/dev/pty18446744073709551615")];
+} rtems_pty_context;
+
+char *telnet_get_pty(rtems_pty_context *ctx, int socket);
 
 #ifdef __cplusplus
 }
diff --git a/cpukit/telnetd/pty.c b/cpukit/telnetd/pty.c
index 3c511f9e98..e32d2eacb9 100644
--- a/cpukit/telnetd/pty.c
+++ b/cpukit/telnetd/pty.c
@@ -29,16 +29,13 @@
 /* #define DEBUG DEBUG_WH */
 
 /*-----------------------------------------*/
-#include <termios.h>
-#include <rtems/termiostypes.h>
 #include <sys/ttycom.h>
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/bspIo.h>
 #include <rtems/pty.h>
+#include <rtems/seterr.h>
 #include <errno.h>
 #include <sys/socket.h>
 /*-----------------------------------------*/
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -63,42 +60,38 @@
 #define IAC_SE     240
 #define IAC_EOR    239
 
-#define SB_MAX    16
-
-extern int rtems_telnetd_maximum_ptys;
-
-struct pty_tt;
-typedef struct pty_tt pty_t;
-
-struct pty_tt {
- char                      devname[17];
- struct rtems_termios_tty *ttyp;
- tcflag_t                  c_cflag;
- int                       opened;
- int                       socket;
- int                       last_cr;
- unsigned                  iac_mode;
- unsigned char             sb_buf[SB_MAX];
- int                       sb_ind;
- int                       width;
- int                       height;
+#define SB_MAX     RTEMS_PTY_SB_MAX
+
+static bool ptyPollInitialize(rtems_termios_tty *,
+  rtems_termios_device_context *, struct termios *,
+  rtems_libio_open_close_args_t *);
+static void ptyShutdown(rtems_termios_tty *,
+  rtems_termios_device_context *, rtems_libio_open_close_args_t *);
+static void ptyPollWrite(rtems_termios_device_context *, const char *, size_t);
+static int ptyPollRead(rtems_termios_device_context *);
+static bool ptySetAttributes(rtems_termios_device_context *,
+  const struct termios *);
+static int my_pty_control(rtems_termios_device_context *,
+  ioctl_command_t, void *);
+
+static const rtems_termios_device_handler pty_handler = {
+  .first_open = ptyPollInitialize,
+  .last_close = ptyShutdown,
+  .poll_read = ptyPollRead,
+  .write = ptyPollWrite,
+  .set_attributes = ptySetAttributes,
+  .ioctl = my_pty_control
 };
 
-
-static int    telnet_pty_inited=FALSE;
-static pty_t *telnet_ptys;
-
-static rtems_device_major_number pty_major;
-
 static
-int send_iac(int minor,unsigned char mode,unsigned char option)
+int send_iac(rtems_pty_context *pty, unsigned char mode, unsigned char option)
 {
   unsigned char buf[3];
 
   buf[0]=IAC_ESC;
   buf[1]=mode;
   buf[2]=option;
-  return write(telnet_ptys[minor].socket,buf,sizeof(buf));
+  return write(pty->socket, buf, sizeof(buf));
 }
 
 /* This procedure returns the devname for a pty slot free.
@@ -106,43 +99,32 @@ int send_iac(int minor,unsigned char mode,unsigned char option)
  *  then the socket argument is closed
  */
 
-char *  telnet_get_pty(int socket)
+char *telnet_get_pty(rtems_pty_context *pty, int socket)
 {
-  int ndx;
-
-  if (telnet_pty_inited) {
-#if 0
-    if ( rtems_telnetd_maximum_ptys < 5 )
-      rtems_telnetd_maximum_ptys = 5;
-
-    telnet_ptys = malloc( rtems_telnetd_maximum_ptys * sizeof (pty_t) );
-#endif
-    if ( !telnet_ptys ) {
-      return NULL;
-    }
-
-    for (ndx=0;ndx<rtems_telnetd_maximum_ptys;ndx++) {
+  rtems_status_code sc;
+  struct timeval t;
+
+  memset(pty, 0, sizeof(*pty));
+  snprintf(pty->name, sizeof(pty->name), "/dev/pty%" PRIuPTR, (uintptr_t)pty);
+  rtems_termios_device_context_initialize(&pty->base, "pty");
+  pty->socket = socket;
+  sc = rtems_termios_device_install(pty->name, &pty_handler, NULL, &pty->base);
+  if (sc != RTEMS_SUCCESSFUL) {
+    close(socket);
+    return NULL;
+  }
 
-      if (telnet_ptys[ndx].socket<0) {
-        struct timeval t;
-        /* set a long polling interval to save CPU time */
-        t.tv_sec=2;
-        t.tv_usec=00000;
-        setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
-        telnet_ptys[ndx].socket=socket;
+  /* set a long polling interval to save CPU time */
+  t.tv_sec=2;
+  t.tv_usec=00000;
+  setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
 
-        /* inform the client that we will echo */
-        send_iac(ndx, IAC_WILL, 1);
+  /* inform the client that we will echo */
+  send_iac(pty, IAC_WILL, 1);
 
-        return telnet_ptys[ndx].devname;
-      };
-    };
-  }
-  close(socket);
-  return NULL;
+  return pty->name;
 }
 
-
 /*-----------------------------------------------------------*/
 /*
  * The NVT terminal is negociated in PollRead and PollWrite
@@ -155,7 +137,7 @@ static const char IAC_BRK_RSP[]="<*Break*>";
 static const char IAC_IP_RSP []="<*Interrupt*>";
 
 static int
-handleSB(pty_t *pty)
+handleSB(rtems_pty_context *pty)
 {
   switch (pty->sb_buf[0]) {
     case 31:  /* NAWS */
@@ -174,13 +156,13 @@ handleSB(pty_t *pty)
   return 0;
 }
 
-static int read_pty(int minor)
+static int ptyPollRead(rtems_termios_device_context *base)
 { /* Characters written to the client side*/
+   rtems_pty_context *pty = (rtems_pty_context *)base;
    unsigned char  value;
    unsigned int  omod;
    int      count;
    int      result;
-   pty_t      *pty=telnet_ptys+minor;
 
    count=read(pty->socket,&value,sizeof(value));
    if (count<0)
@@ -272,33 +254,33 @@ static int read_pty(int minor)
 
        case IAC_WILL:
            if (value==34){
-              send_iac(minor,IAC_DONT,   34);  /*LINEMODE*/
-              send_iac(minor,IAC_DO  ,    1);  /*ECHO    */
+              send_iac(pty,IAC_DONT,   34);  /*LINEMODE*/
+              send_iac(pty,IAC_DO  ,    1);  /*ECHO    */
            } else if (value==31) {
-              send_iac(minor,IAC_DO  ,   31);  /*NAWS    */
+              send_iac(pty,IAC_DO  ,   31);  /*NAWS    */
 #if DEBUG & DEBUG_DETAIL
               printk("replied DO NAWS\n");
 #endif
            } else {
-              send_iac(minor,IAC_DONT,value);
+              send_iac(pty,IAC_DONT,value);
            }
            return -1;
        case IAC_DONT:
            return -1;
        case IAC_DO  :
            if (value==3) {
-              send_iac(minor,IAC_WILL,    3);  /* GO AHEAD*/
+              send_iac(pty,IAC_WILL,    3);  /* GO AHEAD*/
            } else  if (value==1) {
-              send_iac(minor,IAC_WILL,    1);  /* ECHO */
+              send_iac(pty,IAC_WILL,    1);  /* ECHO */
            } else {
-              send_iac(minor,IAC_WONT,value);
+              send_iac(pty,IAC_WONT,value);
            };
            return -1;
        case IAC_WONT:
            if (value==1) {
-             send_iac(minor,IAC_WILL,    1);
+             send_iac(pty,IAC_WILL,    1);
            } else { /* ECHO */
-             send_iac(minor,IAC_WONT,value);
+             send_iac(pty,IAC_WONT,value);
            }
            return -1;
        default:
@@ -321,277 +303,75 @@ static int read_pty(int minor)
   return -1;
 }
 
-/*-----------------------------------------------------------*/
-static int ptySetAttributes(int minor,const struct termios *t);
-static int ptyPollInitialize(int major,int minor,void * arg) ;
-static int ptyShutdown(int major,int minor,void * arg) ;
-static ssize_t ptyPollWrite(int minor, const char * buf, size_t len) ;
-static int ptyPollRead(int minor) ;
-static const rtems_termios_callbacks * pty_get_termios_handlers(int polled) ;
 /*-----------------------------------------------------------*/
 /* Set the 'Hardware'                                        */
 /*-----------------------------------------------------------*/
-static int
-ptySetAttributes(int minor,const struct termios *t) {
-  if (minor<rtems_telnetd_maximum_ptys) {
-   telnet_ptys[minor].c_cflag=t->c_cflag;
-  } else {
-   return -1;
-  };
-  return 0;
+static bool
+ptySetAttributes(rtems_termios_device_context *base, const struct termios *t)
+{
+  rtems_pty_context *pty = (rtems_pty_context *)base;
+  pty->c_cflag = t->c_cflag;
+  return true;
 }
 /*-----------------------------------------------------------*/
-static int
-ptyPollInitialize(int major,int minor,void * arg) {
-  rtems_libio_open_close_args_t * args = (rtems_libio_open_close_args_t*)arg;
-  struct termios t;
-        if (minor<rtems_telnetd_maximum_ptys) {
-         if (telnet_ptys[minor].socket<0) return -1;
-   telnet_ptys[minor].opened=TRUE;
-   telnet_ptys[minor].ttyp= (struct rtems_termios_tty *) args->iop->data1;
-   telnet_ptys[minor].iac_mode=0;
-   telnet_ptys[minor].sb_ind=0;
-   telnet_ptys[minor].width=0;
-   telnet_ptys[minor].height=0;
-   t.c_cflag=B9600|CS8;/* termios default */
-   return ptySetAttributes(minor,&t);
-  } else {
-   return -1;
-  }
+static bool
+ptyPollInitialize(rtems_termios_tty *ttyp,
+  rtems_termios_device_context *base, struct termios *t,
+  rtems_libio_open_close_args_t *args)
+{
+  rtems_pty_context *pty = (rtems_pty_context *)base;
+  pty->ttyp = ttyp;
+  pty->iac_mode = 0;
+  pty->sb_ind = 0;
+  pty->width = 0;
+  pty->height = 0;
+  return ptySetAttributes(&pty->base, t);
 }
 /*-----------------------------------------------------------*/
-static int
-ptyShutdown(int major,int minor,void * arg) {
-  if (minor<rtems_telnetd_maximum_ptys) {
-    telnet_ptys[minor].opened=FALSE;
-    if (telnet_ptys[minor].socket>=0) close(telnet_ptys[minor].socket);
-      telnet_ptys[minor].socket=-1;
-    chown(telnet_ptys[minor].devname,2,0);
-  } else {
-    return -1;
-  }
-  return 0;
+static void
+ptyShutdown(rtems_termios_tty *ttyp,
+  rtems_termios_device_context *base, rtems_libio_open_close_args_t *arg)
+{
+  rtems_pty_context *pty = (rtems_pty_context *)base;
+  close(pty->socket);
 }
 /*-----------------------------------------------------------*/
 /* Write Characters into pty device                          */
 /*-----------------------------------------------------------*/
-static ssize_t
-ptyPollWrite(int minor, const char * buf, size_t len) {
-  size_t count;
-  if (minor<rtems_telnetd_maximum_ptys) {
-    if (telnet_ptys[minor].socket<0)
-      return -1;
-    count=write(telnet_ptys[minor].socket,buf,len);
-  } else {
-   count=-1;
-  }
-  return count;
-}
-/*-----------------------------------------------------------*/
-static int
-ptyPollRead(int minor) {
-  int result;
-
-  if (minor<rtems_telnetd_maximum_ptys) {
-    if (telnet_ptys[minor].socket<0)
-      return -1;
-    result=read_pty(minor);
-    return result;
-  }
-  return -1;
-}
-/*-----------------------------------------------------------*/
-/*  pty_initialize
- *
- *  This routine initializes the pty IO driver.
- *
- *  Input parameters: NONE
- *
- *  Output parameters:  NONE
- *
- *  Return values:
- */
-/*-----------------------------------------------------------*/
-static
-rtems_device_driver my_pty_initialize(
-  rtems_device_major_number  major,
-  rtems_device_minor_number  minor,
-  void                      *arg
-)
-{
-  int ndx;
-  rtems_status_code status;
-
-  if ( rtems_telnetd_maximum_ptys < 5 )
-    rtems_telnetd_maximum_ptys = 5;
-
-  telnet_ptys = malloc( rtems_telnetd_maximum_ptys * sizeof (pty_t) );
-
-  /*
-   * Set up ptys
-   */
-
-  for (ndx=0;ndx<rtems_telnetd_maximum_ptys;ndx++) {
-    /* devname is included in the structure */
-    sprintf(telnet_ptys[ndx].devname,"/dev/pty%02X",ndx);
-    telnet_ptys[ndx].ttyp    =  NULL;
-    telnet_ptys[ndx].c_cflag = CS8|B9600;
-    telnet_ptys[ndx].socket  = -1;
-    telnet_ptys[ndx].opened  = FALSE;
-    telnet_ptys[ndx].sb_ind  = 0;
-    telnet_ptys[ndx].width   = 0;
-    telnet_ptys[ndx].height  = 0;
-
-  }
-
-  /*
-   * Register the devices
-   */
-  for (ndx=0;ndx<rtems_telnetd_maximum_ptys;ndx++) {
-    status = rtems_io_register_name(telnet_ptys[ndx].devname, major, ndx);
-    if (status != RTEMS_SUCCESSFUL)
-        rtems_fatal_error_occurred(status);
-    chmod(telnet_ptys[ndx].devname,0660);
-    chown(telnet_ptys[ndx].devname,2,0); /* tty,root*/
-  };
-  syslog(
-    LOG_KERN | LOG_INFO,
-    "/dev/pty%X../dev/pty%X (%d) pseudo-terminals registered.\n",
-    0,
-    rtems_telnetd_maximum_ptys - 1,
-    rtems_telnetd_maximum_ptys
-  );
-
-  return RTEMS_SUCCESSFUL;
-}
-
-static int pty_do_finalize(void)
+static void
+ptyPollWrite(rtems_termios_device_context *base, const char *buf, size_t len)
 {
-    int ndx;
-    rtems_status_code status;
+  rtems_pty_context *pty = (rtems_pty_context *)base;
 
-    if ( !telnet_pty_inited )
-      return 0;
-
-    for (ndx=0;ndx<rtems_telnetd_maximum_ptys;ndx++) {
-      if (telnet_ptys[ndx].opened) {
-          fprintf(stderr,
-            "There are still opened PTY devices, unable to proceed\n");
-          return -1;
-      }
-    }
-    if (RTEMS_SUCCESSFUL != rtems_io_unregister_driver(pty_major)) {
-        fprintf(stderr,"Unable to remove this driver\n");
-        return -1;
+  while (len > 0) {
+    ssize_t n = write(pty->socket, buf, len);
+    if (n <= 0) {
+      break;
     }
-    for (ndx=0;ndx<rtems_telnetd_maximum_ptys;ndx++) {
-        /* rtems_io_register_name() actually creates a node in the filesystem
-         * (mknod())
-         */
-        status = (rtems_status_code)unlink(telnet_ptys[ndx].devname);
-        if (status != RTEMS_SUCCESSFUL)
-          perror("removing pty device node from file system");
-        else {
-          telnet_ptys[ndx].devname[0] = '\0';
-        }
-    };
-
-    free ( telnet_ptys );
-
-    fprintf(stderr,"PTY driver unloaded successfully\n");
-    telnet_pty_inited=FALSE;
-    return 0;
-}
-
-/*
- *  Open entry point
- */
-
-static
-rtems_device_driver my_pty_open(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg
-)
-{
-  rtems_status_code sc;
-  sc = rtems_termios_open(major,minor,arg,pty_get_termios_handlers(FALSE));
-  return sc;
-}
-
-/*
- *  Close entry point
- */
-
-static
-rtems_device_driver my_pty_close(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg
-)
-{
-  return rtems_termios_close(arg);
-}
 
-/*
- * read bytes from the pty
- */
-
-static
-rtems_device_driver my_pty_read(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg
-)
-{
-  return rtems_termios_read(arg);
-}
-
-/*
- * write bytes to the pty
- */
-
-static
-rtems_device_driver my_pty_write(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg
-)
-{
-  return rtems_termios_write(arg);
+    buf += (size_t)n;
+    len -= (size_t)n;
+  }
 }
 
-/*
- *  IO Control entry point
- */
-
-static
-rtems_device_driver my_pty_control(
-  rtems_device_major_number major,
-  rtems_device_minor_number minor,
-  void                    * arg
-)
+static int
+my_pty_control(rtems_termios_device_context *base,
+  ioctl_command_t request, void *buffer)
 {
-  rtems_libio_ioctl_args_t *args = (rtems_libio_ioctl_args_t*)arg;
-  struct winsize           *wp = (struct winsize*)args->buffer;
-  pty_t                    *p = &telnet_ptys[minor];
-
-  switch (args->command) {
+  rtems_pty_context *p = (rtems_pty_context *)base;
+  struct winsize *wp = buffer;
 
+  switch (request) {
     case TIOCGWINSZ:
-
       wp->ws_row = p->height;
       wp->ws_col = p->width;
-      args->ioctl_return=0;
 #if DEBUG & DEBUG_WH
       fprintf(stderr,
           "ioctl(TIOCGWINSZ), returning %ix%i\n",
           wp->ws_col,
           wp->ws_row);
 #endif
-
-      return RTEMS_SUCCESSFUL;
-
+      break;
     case TIOCSWINSZ:
 #if DEBUG & DEBUG_WH
       fprintf(stderr,
@@ -602,61 +382,11 @@ rtems_device_driver my_pty_control(
 
       p->height = wp->ws_row;
       p->width  = wp->ws_col;
-      args->ioctl_return=0;
-
-      return RTEMS_SUCCESSFUL;
-
+      break;
     default:
-
-     break;
-  }
-
-  return rtems_termios_ioctl(arg);
-}
-
-static rtems_driver_address_table drvPty = {
-    my_pty_initialize,
-    my_pty_open,
-    my_pty_close,
-    my_pty_read,
-    my_pty_write,
-    my_pty_control
-};
-
-/*-----------------------------------------------------------*/
-static const rtems_termios_callbacks pty_poll_callbacks = {
-  ptyPollInitialize,  /* FirstOpen */
-  ptyShutdown,        /* LastClose */
-  ptyPollRead,        /* PollRead  */
-  ptyPollWrite,       /* Write */
-  ptySetAttributes,   /* setAttributes */
-  NULL,               /* stopRemoteTX */
-  NULL,               /* StartRemoteTX */
-  0                   /* outputUsesInterrupts */
-};
-/*-----------------------------------------------------------*/
-static const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {
-  return &pty_poll_callbacks;
-}
-/*-----------------------------------------------------------*/
-
-static int pty_do_initialize(void)
-{
-  if ( !telnet_pty_inited ) {
-    if (RTEMS_SUCCESSFUL==rtems_io_register_driver(0, &drvPty, &pty_major))
-      telnet_pty_inited=TRUE;
-    else
-      fprintf(stderr,"WARNING: registering the PTY driver FAILED\n");
+      rtems_set_errno_and_return_minus_one(EINVAL);
+      break;
   }
-  return telnet_pty_inited;
-}
 
-int telnet_pty_initialize(void)
-{
-  return pty_do_initialize();
-}
-
-int telnet_pty_finalize(void)
-{
-  return pty_do_finalize();
+  return 0;
 }
diff --git a/cpukit/telnetd/telnetd.c b/cpukit/telnetd/telnetd.c
index 43e00365b5..a661eb0088 100644
--- a/cpukit/telnetd/telnetd.c
+++ b/cpukit/telnetd/telnetd.c
@@ -64,14 +64,11 @@
 
 #define PARANOIA
 
-extern char *telnet_get_pty(int socket);
-extern int   telnet_pty_initialize(void);
-
 struct shell_args {
-  char *devname;
-  void *arg;
-  char  peername[16];
-  char  delete_myself;
+  rtems_pty_context  pty;
+  void              *arg;
+  char               peername[16];
+  char               delete_myself;
 };
 
 typedef union uni_sa {
@@ -107,17 +104,23 @@ static const rtems_id (*telnetd_spawn_task)(
   void *
 ) = telnetd_dflt_spawn;
 
-static char *grab_a_Connection(
+static struct shell_args *grab_a_Connection(
   int des_socket,
   uni_sa *srv,
   char *peername,
   int sz
 )
 {
-  char *rval = 0;
+  struct shell_args *args = NULL;
   socklen_t size_adr = sizeof(srv->sin);
   int acp_sock;
 
+  args = malloc(sizeof(*args));
+  if (args == NULL) {
+    perror("telnetd:malloc");
+    goto bailout;
+  }
+
   acp_sock = accept(des_socket,&srv->sa,&size_adr);
 
   if (acp_sock<0) {
@@ -125,7 +128,7 @@ static char *grab_a_Connection(
     goto bailout;
   };
 
-  if ( !(rval=telnet_get_pty(acp_sock)) ) {
+  if (telnet_get_pty(&args->pty, acp_sock) == NULL) {
     syslog( LOG_DAEMON | LOG_ERR, "telnetd: unable to obtain PTY");
     /* NOTE: failing 'do_get_pty()' closed the socket */
     goto bailout;
@@ -138,12 +141,12 @@ static char *grab_a_Connection(
   syslog(LOG_DAEMON | LOG_INFO,
       "telnetd: accepted connection from %s on %s",
       peername,
-      rval);
+      args->pty.name);
 #endif
 
 bailout:
 
-  return rval;
+  return args;
 }
 
 
@@ -160,6 +163,7 @@ static void release_a_Connection(char *devname, char *peername, FILE **pstd, int
   while (--n>=0)
     if (pstd[n]) fclose(pstd[n]);
 
+  unlink(devname);
 }
 
 static int sockpeername(int sock, char *buf, int bufsz)
@@ -186,7 +190,6 @@ rtems_task_telnetd(void *task_argument)
 {
   int                des_socket;
   uni_sa             srv;
-  char              *devname;
   char               peername[16];
   int                i=1;
   int                size_adr;
@@ -243,22 +246,19 @@ rtems_task_telnetd(void *task_argument)
         );
       }
     } else {
-      devname = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
+      arg = grab_a_Connection(des_socket, &srv, peername, sizeof(peername));
 
-      if ( !devname ) {
+      if (arg == NULL) {
         /* if something went wrong, sleep for some time */
         sleep(10);
         continue;
       }
 
-      arg = malloc( sizeof(*arg) );
-
-      arg->devname = devname;
       arg->arg = telnetd_config->arg;
       strncpy(arg->peername, peername, sizeof(arg->peername));
 
       telnetd_task_id = telnetd_spawn_task(
-        devname,
+        arg->pty.name,
         telnetd_config->priority,
         telnetd_config->stack_size,
         spawned_shell,
@@ -278,9 +278,9 @@ rtems_task_telnetd(void *task_argument)
          * a stream...
          */
 
-        if ( !(dummy=fopen(devname,"r+")) )
+        if ( !(dummy=fopen(arg->pty.name,"r+")) )
           perror("Unable to dummy open the pty, losing a slot :-(");
-        release_a_Connection(devname, peername, &dummy, 1);
+        release_a_Connection(arg->pty.name, peername, &dummy, 1);
         free(arg);
         sleep(2); /* don't accept connections too fast */
       }
@@ -315,14 +315,6 @@ rtems_status_code rtems_telnetd_start(const rtems_telnetd_config_table* config)
     return RTEMS_NO_MEMORY;
   }
 
-
-  if ( !telnet_pty_initialize() ) {
-    fprintf(stderr, "telnetd cannot initialize PTY driver\n");
-    free(telnetd_config);
-    telnetd_config = NULL;
-    return RTEMS_IO_ERROR;
-  }
-
   *telnetd_config = *config;
 
   /* Check priority */
@@ -396,7 +388,7 @@ spawned_shell(void *targ)
 
   /* redirect stdio */
   for (i=0; i<3; i++) {
-    if ( !(nstd[i]=fopen(arg->devname,"r+")) ) {
+    if ( !(nstd[i]=fopen(arg->pty.name,"r+")) ) {
       perror("unable to open stdio");
       goto cleanup;
     }
@@ -418,13 +410,13 @@ spawned_shell(void *targ)
     start = rtems_shell_login_prompt(
       stdin,
       stderr,
-      arg->devname,
+      arg->pty.name,
       telnetd_config->login_check
     );
     login_failed = !start;
   }
   if (start) {
-    telnetd_config->command( arg->devname, arg->arg);
+    telnetd_config->command( arg->pty.name, arg->arg);
   }
 
   stdin  = ostd[0];
@@ -440,7 +432,7 @@ spawned_shell(void *targ)
   }
 
 cleanup:
-  release_a_Connection(arg->devname, arg->peername, nstd, i);
+  release_a_Connection(arg->pty.name, arg->peername, nstd, i);
   free(arg);
 }
 
-- 
2.16.4




More information about the devel mailing list