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