Hi all!
I cleaned up my patches. They can be applied on snapshot-1999-01-28.
client.c:
- I moved the termios struct from pty_request to client_session to be able to
  restore the original term settings on exit. (I put the restoring code to
  close_client_session. Maybe there is better place for it.)
  A raw mode flag and a tty file descriptor is also placed into
  the client_session object.
- Setting the client term to raw mode now happens in do_pty_result. In this
  func I also fill the termios struct and set the raw flag of the
  client_session instance.
server.c:
- The most painful change is that if we have a PTY we _must_ pipe the stderr
  through the PTY! If we don't do this, programs which want to set the
  terminal params, will fail with a message like this: "stderr: invalid
  argument". And also bash will look bad, because the prompt is printed to the
  stderr, and if it goes through a separate channel, the client will display
  it incorrectly on its raw terminal.
- Setting the controlling terminal moved before closeing pty->slave.
tty.c:
- tty_encode_term_mode created
- hacked a little bit on setctty. I think Ray's daemonisation code will make
  this hack unnecessary.
- fixed two typos

I started a very preliminary /dev/ptmx support, but Ray has better patch for
it.

Greets,
Keresztg

+ Keresztfalvi Gabor
+ Student of Technical University of Budapest
+ mailto: [EMAIL PROTECTED]  [EMAIL PROTECTED]  [EMAIL PROTECTED]
+ http://www.piar.hu/~keresztg/   Pubkey: finger [EMAIL PROTECTED]


--- ../../lsh-snapshot-1999-01-28.orig/src/tty.c        Thu Jan 28 09:56:14 1999
+++ tty.c       Sun Feb 14 02:40:20 1999
@@ -27,6 +27,7 @@
 #include "parse.h"
 #include "ssh.h"
 #include "werror.h"
+#include "xalloc.h"
 
 #include <errno.h>
 #include <string.h>
@@ -46,11 +47,20 @@
 }
 
 /* NOTE: This function also makes the current process a process group
- * leader. */
+ * leader. 
+ * +G: It's really POSIX dependent... 
+ * +G: Some ideas got from screen-3.7.6
+ * +G: And it's really a mess... contributions/fixes welcome for non POSIX
+ *     systems
+ */
 int tty_setctty(int newtty)
 {
   int oldtty;
+  pid_t mpid;
+
+  mpid=getpid();
 
+#ifdef TIOCNOTTY
   oldtty = open("/dev/tty", O_RDWR | O_NOCTTY);
   if (oldtty >= 0)
   {
@@ -64,16 +74,26 @@
         return 0;
       }
   }
+#endif
+
   if (setsid() < 0)
     werror("tty_setctty: setsid() failed, already process group leader?\n"
           "   (errno = %d): %s\n", errno, strerror(errno));
   
+#ifdef TIOCSCTTY
   if (ioctl(newtty, TIOCSCTTY, NULL) == -1)
     {
-      werror("tty_setctty: Failed to set the controlling tty.\n"
+      werror("tty_setctty: ioctl(newtty,TIOCSCTTY,NULL) failed.\n"
             "   (errno = %d): %s\n", errno, strerror(errno));
       return 0;
     }
+#endif
+
+  if (tcsetpgrp(newtty,mpid) == -1)
+  {
+    werror("tty_setctty: tcsetpgrp(newtty,mpid) failed.\n"
+          "   (errno = %d): %s\n", errno, strerror(errno));
+  }
   
   return 1;
 }
@@ -133,7 +153,7 @@
 #else
   -1,
 #endif
-#ifdef VINTR
+#ifdef VERASE
   VERASE, 
 #else
   -1,
@@ -403,9 +423,43 @@
 };
 
 /* FIXME: Dummy function. */
+/* In first approach it's fixed :)  Keresztg */
+/* but FIXME: TTY_?SPEED not handled */
+#define PARSE_FLAGS(cc,inios,offset)           \
+debug("tty_encode_term_mode: termios flag 0%o (offset %d)\n",inios,offset); \
+for (i=0;i<sizeof(cc)/sizeof(cc[0]);i++)       \
+       if (cc[i])                              \
+       {                                       \
+               *(bp++)=i+offset;               \
+               r=inios&cc[i] ? 1 : 0;          \
+               bp[0]=bp[1]=bp[2]=0;            \
+               bp[3]=r;                        \
+               bp+=4;                          \
+       }                                       \
+
 struct lsh_string *tty_encode_term_mode(struct termios *ios)
 {
-  return ssh_format("");
+       unsigned int i;
+       UINT8 *bp,r;
+       struct lsh_string *new;
+       
+       new=lsh_string_alloc(650);      /* +G: I hope it's quite enough pessimistic */
+       bp=new->data;                   /* +G: Is this way of string handling 
+"allowed"? */
+       for (i=0;i<sizeof(cc_ndx)/sizeof(cc_ndx[0]);i++)
+       {
+               if (cc_ndx[i]!=-1)
+               {
+                       *(bp++)=i+1;
+                       WRITE_UINT32(bp,ios->c_cc[cc_ndx[i]]);
+                       bp+=4;
+               }
+       }
+       PARSE_FLAGS(cc_iflags,ios->c_iflag,30);
+       PARSE_FLAGS(cc_lflags,ios->c_lflag,50);
+       PARSE_FLAGS(cc_oflags,ios->c_oflag,70);
+       PARSE_FLAGS(cc_cflags,ios->c_cflag,90);
+       *(bp++)=0;
+       return(new);
 }
 
 #define TTY_SET_VALUE(target, param, table, index)     \
@@ -468,7 +522,7 @@
            TTY_SET_VALUE(ios->c_cc, param, cc_ndx, opcode - 1);
          else if (opcode < 50)
            TTY_SET_FLAG(ios->c_iflag, param, cc_iflags, opcode - 30);
-         else if (opcode < 75)
+         else if (opcode < 70)
            TTY_SET_FLAG(ios->c_lflag, param, cc_lflags, opcode - 50);
          else if (opcode < 90)
            TTY_SET_FLAG(ios->c_oflag, param, cc_oflags, opcode - 70);
--- ../../lsh-snapshot-1999-01-28.orig/src/server.c     Thu Jan 28 09:51:26 1999
+++ server.c    Sun Feb 14 18:44:19 1999
@@ -835,11 +835,16 @@
         {
           if ((out[1] = dup(pty->slave)) != -1) 
             {
-             if (make_pipe(err))
+             if ((err[0] = dup(pty->master)) != -1)
+               {
+                 if ((err[1] = dup(pty->slave)) != -1 )
                {
                  /* Success! */
                  return 1;
                }
+                   else close(err[0]);
+               }
+               else close(out[1]);
               saved_errno = errno;
             }
          else
@@ -963,6 +968,8 @@
           * close-on-exec flag for all fd:s handled by the
           * backend. */
            
+         if (using_pty)
+           tty_setctty(session->pty->slave);
          if (dup2(in[0], STDIN_FILENO) < 0)
            {
              wwrite("Can't dup stdin!\n");
@@ -994,8 +1001,6 @@
          close(err[0]);
          close(err[1]);
            
-         if (using_pty)
-           tty_setctty(session->pty->slave);
 #if 1
 #if USE_LOGIN_DASH_CONNVENTION
          {
@@ -1175,7 +1180,6 @@
               session->term = term;
               tty_decode_term_mode(&ios, mode_length, mode); 
              
-             /* cfmakeraw(&ios); */
               if (tty_setattr(pty->slave, &ios) &&
                   tty_setwinsize(pty->slave,
                                 width, height, width_p, height_p))
--- ../../lsh-snapshot-1999-01-28.orig/src/client.c     Thu Jan 28 09:10:18 1999
+++ client.c    Sun Feb 14 18:36:22 1999
@@ -344,6 +344,11 @@
        (out object io_fd)
        (err object io_fd)
 
+       ; Saved term settings
+       (ios simple "struct termios")
+       (tty . int)
+       (raw . int)
+
        ; Where to save the exit code.
        (exit_status simple "int *")))
 */
@@ -353,6 +358,11 @@
 {
   CAST(client_session, session, c);
   
+  if (session->raw)
+  {
+    if (!tty_setattr(session->tty,&(session->ios)))
+       werror("close_client_session: Can't restore terminal settings!\n");
+  }
   close_fd(&session->in->super, 0);
 #if 0
   close_fd(&session->out->super, 0);
@@ -642,8 +652,6 @@
   closure->super.open_confirm = NULL;
   closure->super.open_failure = NULL;
   
-  /* tty_makeraw(0); */
-
   for (req = closure->requests; req; req = req->next)
     {
       assert(req->want_reply == (req->essential || req->result));
@@ -785,7 +793,7 @@
      (vars
        ; An open fd connected to a tty (most likely, /dev/tty opened by main).
        (tty . int)
-       (ios simple "struct termios")
+       (raw . int)
        (term string)
        (width . UINT32)
        (height . UINT32)
@@ -809,18 +817,34 @@
 }
 
 static int do_pty_result(struct request_info *r,
-                        struct ssh_channel *ignored UNUSED,
+                        struct ssh_channel *ignored,
                         int res)
 {
   CAST(pty_request, req, r);
+  CAST(client_session, ign, ignored);
 
   verbose("lsh: pty request %s.\n", res ? "successful" : "failed");
   
+  ign->raw=0;
   if (res)
     {
-      if (!tty_setattr(req->tty, &req->ios))
+      if (req->raw)
+      {
+       ign->raw=1;
+       ign->tty=req->tty;
+       if (!tty_getattr(ign->tty,&(ign->ios)))
+       {
+         werror("do_pty_result: "
+               "Getting the attributes of the local terminal failed. Won't be 
+restored!\n");
+         ign->raw=0;
+       }
+        if (!tty_makeraw(ign->tty))
+        {
        werror("do_pty_result: "
               "Setting the attributes of the local terminal failed.\n");
+         ign->raw=0;
+       }
+      }
     }
   return LSH_OK | LSH_GOON;
 }
@@ -829,6 +853,7 @@
                                      struct request_info *next)
 {
   NEW(pty_request, req);
+  struct termios ios;
 
   char *term = getenv("TERM");
 
@@ -839,16 +864,13 @@
   
   req->tty = fd;
   req->term = term ? format_cstring(term) : ssh_format("");
+  req->raw = raw;
   
-  if (tty_getattr(fd, &req->ios)
+  if (tty_getattr(fd, &ios)
       && tty_getwinsize(fd, &req->width, &req->height,
                        &req->width_p, &req->height_p))
     {
-      if (raw)
-       cfmakeraw(&req->ios);
-  
-      req->modes = tty_encode_term_mode(&req->ios);
-      
+      req->modes = tty_encode_term_mode(&ios);
       req->super.result = do_pty_result;
     }
   else

Reply via email to