diff --git a/src/modules/files/termios.c b/src/modules/files/termios.c
index 22d91db84dcef800ea40de4720827b53f6703202..7b37f0cda29c696fbe85f6188358a75c934107d0 100644
--- a/src/modules/files/termios.c
+++ b/src/modules/files/termios.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: termios.c,v 1.2 1998/12/17 02:06:50 mirar Exp $");
+RCSID("$Id: termios.c,v 1.3 1998/12/18 17:26:55 mirar Exp $");
 #include "file_machine.h"
 
 #if defined(HAVE_TERMIOS_H)
@@ -7,6 +7,7 @@ RCSID("$Id: termios.c,v 1.2 1998/12/17 02:06:50 mirar Exp $");
 #include <termios.h>
 #include <unistd.h>
 #include <errno.h>
+#include <sys/ioctl.h>
 
 #include "fdlib.h"
 #include "interpret.h"
@@ -26,18 +27,22 @@ RCSID("$Id: termios.c,v 1.2 1998/12/17 02:06:50 mirar Exp $");
 **!
 **!	the returned value/the parameter is a mapping on the form
 **!	<pre>
-**!		"ispeed":baud rate
-**!		"ospeed":baud rate
-**!		flag:0|1
+**!		"ispeed":    baud rate
+**!		"ospeed":    baud rate
+**!		"csize":     character size (5,6,7 or 8)
+**!		"rows":      terminal rows 
+**!		"columns":   terminal columns  
+**!		flag:        0 or 1
+**!		control char:value
 **!		...
 **!	</pre>
 **!     where 'flag' is the string describing the termios 
 **!     (input, output, control and local mode) flags 
 **!     (see the manpage for termios or the tutorial).
 **!
-**!	Note that tcsetattr always will set the attributes
-**!	in the mapping; correct use would be something like:
-**!	<tt>fd->tcsetattr(fd->tcgetattr()|(["myflag":1]));</tt>
+**!	Note that tcsetattr always _changes_ the attributes;
+**!	correct use to set a flag would be something like:
+**!	<tt>fd->tcsetattr((["myflag":1]));</tt>
 **!
 **!	the argument 'when' to tcsetattr describes when the 
 **!	changes are to take effect:
@@ -46,6 +51,13 @@ RCSID("$Id: termios.c,v 1.2 1998/12/17 02:06:50 mirar Exp $");
 **!	"TCSAFLUSH": the change occurs after all output has been written,
 **!	and empties input buffers.
 **!
+**!	Example for setting the terminal in raw mode:
+**!	   Stdio.stdin->tcsetattr((["ECHO":0,"ICANON":0,"VMIN":0,"VTIME":0]));
+**!
+**!	Note: Unknown flags are ignored by tcsetattr().
+**!	Terminal rows and columns settring by tcsetattr() is not
+**!	currently supported.
+**!
 **!	returns 0 if failed.
 */
 
@@ -77,16 +89,21 @@ void file_tcgetattr(INT32 args)
    push_text(sflag); \
    push_int(!!(ti.where&flag)); \
    n++; 
+#define TERMIOS_CHAR(c,sc) \
+   push_text(sc); \
+   push_int(ti.c_cc[c]); \
+   n++; 
 
 #include "termios_flags.h"
 
 #undef TERMIOS_FLAG
+#undef TERMIOS_CHAR
 
    push_text("ospeed");
    switch (cfgetospeed(&ti))
    {
 #define TERMIOS_SPEED(B,V) case B: push_int(V); break;
-#include "termios_speeds.h"
+#include "termios_flags.h"
       default: push_int(-1);
    }
    n++;
@@ -94,12 +111,50 @@ void file_tcgetattr(INT32 args)
    push_text("ispeed");
    switch (cfgetispeed(&ti))
    {
-#include "termios_speeds.h"
+#include "termios_flags.h"
 #undef TERMIOS_SPEED
       default: push_int(-1);
    }
    n++;
 
+#ifdef CSIZE
+   push_text("csize");
+   switch (ti.c_cflag&CSIZE)
+   {
+#ifdef CS8
+      case CS8: push_int(8); break;
+#endif
+#ifdef CS7
+      case CS7: push_int(7); break;
+#endif
+#ifdef CS6
+      case CS6: push_int(6); break;
+#endif
+#ifdef CS5
+      case CS5: push_int(5); break;
+#endif
+      default:
+	 push_int(-1);
+   }
+   n++;
+#endif
+
+#ifdef TIOCGWINSZ
+   {
+      struct winsize winsize;
+      if (!ioctl(FD,TIOCGWINSZ,&winsize))
+      {
+	 push_text("rows");
+	 push_int(winsize.ws_row);
+	 n++;
+	 push_text("columns");
+	 push_int(winsize.ws_col);
+	 n++;
+      }
+   }
+#endif
+
+
    f_aggregate_mapping(n*2);
 }
 
@@ -135,55 +190,112 @@ void file_tcsetattr(INT32 args)
    if (sp[-1].type!=T_MAPPING)
       error("illegal argument 1 to tcsetattr\n");
 
-   /* just zero these */
-   ti.c_iflag=0;
-   ti.c_oflag=0;
-   ti.c_cflag=0;
-   ti.c_lflag=0;
+   /* read attr to edit */
+   if (tcgetattr(FD,&ti)) /* error */
+   {
+      ERRNO=errno;
+      push_int(0);
+      return;
+   }
 
 #define TERMIOS_FLAG(where,flag,sflag) \
    stack_dup(); \
    push_text(sflag); \
    f_index(2); \
-   if (sp[-1].type!=T_INT)  \
-      error("illegal argument 1 to tcsetattr: key %s has illegal value",sflag); \
-   if (sp[-1].u.integer) ti.where|=flag; \
+   if (!IS_UNDEFINED(sp-1)) \
+   { \
+      if (sp[-1].type!=T_INT)  \
+         error("illegal argument 1 to tcsetattr: key %s has illegal value",sflag); \
+      if (sp[-1].u.integer) ti.where|=flag; else ti.where&=~flag; \
+   } \
+   pop_stack();
+
+#define TERMIOS_CHAR(cc,scc) \
+   stack_dup(); \
+   push_text(scc); \
+   f_index(2); \
+   if (!IS_UNDEFINED(sp-1)) \
+   { \
+      if (sp[-1].type!=T_INT)  \
+         error("illegal argument 1 to tcsetattr: key %s has illegal value",scc); \
+      ti.c_cc[cc]=(char)sp[-1].u.integer; \
+   } \
    pop_stack();
 
 #include "termios_flags.h"
 
 #undef TERMIOS_FLAG
+#undef TERMIOS_CHAR
+
+#ifdef CSIZE
+   stack_dup();
+   push_text("csize");
+   f_index(2);
+
+   if (!IS_UNDEFINED(sp-1)) 
+   {
+      if (sp[-1].type!=T_INT)  
+   	 error("illegal argument 1 to tcsetattr: key %s has illegal value","csize"); 
+
+      switch (sp[-1].u.integer)
+      {
+#ifdef CS8
+	 case 8: ti.c_cflag=(ti.c_cflag&~CSIZE)|CS8; break;
+#endif
+#ifdef CS7
+	 case 7: ti.c_cflag=(ti.c_cflag&~CSIZE)|CS8; break;
+#endif
+#ifdef CS6
+	 case 6: ti.c_cflag=(ti.c_cflag&~CSIZE)|CS8; break;
+#endif
+#ifdef CS5
+	 case 5: ti.c_cflag=(ti.c_cflag&~CSIZE)|CS8; break;
+#endif
+	 default:
+	    error("illegal argument 1 to tcsetattr: value of key %s is not a valid char size","csize"); 
+      }
+   }
+   pop_stack();
 
+#endif
+   
+   
    stack_dup(); 
    push_text("ospeed");
    f_index(2); 
-   if (sp[-1].type!=T_INT)  
-      error("illegal argument 1 to tcsetattr: key %s has illegal value","ospeed"); 
-   switch (sp[-1].u.integer)
+   if (!IS_UNDEFINED(sp-1)) 
    {
-#define TERMIOS_SPEED(B,V) case V: push_int(B); break;
-#include "termios_speeds.h"
-      default:
-	 error("illegal argument 1 to tcsetattr, value of key %s in not a valid baud rate\n","ospeed");
+      if (sp[-1].type!=T_INT)  
+   	 error("illegal argument 1 to tcsetattr: key %s has illegal value","ospeed"); 
+      switch (sp[-1].u.integer)
+      {
+   #define TERMIOS_SPEED(B,V) case V: push_int(B); break;
+   #include "termios_flags.h"
+   	 default:
+   	    error("illegal argument 1 to tcsetattr, value of key %s is not a valid baud rate\n","ospeed");
+      }
+      cfsetospeed(&ti,sp[-1].u.integer);
+      pop_stack();
    }
-   cfsetospeed(&ti,sp[-1].u.integer);
-   pop_stack();
    pop_stack();
 
    stack_dup(); 
    push_text("ispeed");
    f_index(2); 
-   if (sp[-1].type!=T_INT)  
-      error("illegal argument 1 to tcsetattr: key %s has illegal value","ospeed"); 
-   switch (sp[-1].u.integer)
+   if (!IS_UNDEFINED(sp-1)) 
    {
-#include "termios_speeds.h"
-#undef TERMIOS_SPEED
-      default:
-	 error("illegal argument 1 to tcsetattr, value of key %s in not a valid baud rate\n","ispeed");
+      if (sp[-1].type!=T_INT)  
+   	 error("illegal argument 1 to tcsetattr: key %s has illegal value","ospeed"); 
+      switch (sp[-1].u.integer)
+      {
+   #include "termios_flags.h"
+   #undef TERMIOS_SPEED
+   	 default:
+   	    error("illegal argument 1 to tcsetattr, value of key %s is not a valid baud rate\n","ispeed");
+      }
+      cfsetispeed(&ti,sp[-1].u.integer);
+      pop_stack();
    }
-   cfsetispeed(&ti,sp[-1].u.integer);
-   pop_stack();
    pop_stack();
 
    pop_stack(); /* lose the mapping */
diff --git a/src/modules/files/termios_flags.h b/src/modules/files/termios_flags.h
index 644157d15f2f2bf5135451d678414fd3c4fa0f51..3cf79307394c9f903d7d7ff5ea7739ba424ca4c1 100644
--- a/src/modules/files/termios_flags.h
+++ b/src/modules/files/termios_flags.h
@@ -1,3 +1,5 @@
+#ifdef TERMIOS_FLAG
+
 #ifdef IGNBRK
   TERMIOS_FLAG(c_iflag,IGNBRK,"IGNBRK")
 #endif
@@ -65,24 +67,6 @@
 #ifdef OFDEL
   TERMIOS_FLAG(c_oflag,OFDEL,"OFDEL")
 #endif
-#ifdef NLDLY
-  TERMIOS_FLAG(c_oflag,NLDLY,"NLDLY")
-#endif
-#ifdef CRDLY
-  TERMIOS_FLAG(c_oflag,CRDLY,"CRDLY")
-#endif
-#ifdef TABDLY
-  TERMIOS_FLAG(c_oflag,TABDLY,"TABDLY")
-#endif
-#ifdef BSDLY
-  TERMIOS_FLAG(c_oflag,BSDLY,"BSDLY")
-#endif
-#ifdef VTDLY
-  TERMIOS_FLAG(c_oflag,VTDLY,"VTDLY")
-#endif
-#ifdef FFDLY
-  TERMIOS_FLAG(c_oflag,FFDLY,"FFDLY")
-#endif
 #ifdef OXTABS
   TERMIOS_FLAG(c_cflag,OXTABS,"OXTABS")
 #endif
@@ -90,18 +74,6 @@
   TERMIOS_FLAG(c_cflag,ONOEOT,"ONOEOT")
 #endif
 
-#ifdef CS5
-  TERMIOS_FLAG(c_cflag,CS5,"CS5")
-#endif
-#ifdef CS6
-  TERMIOS_FLAG(c_cflag,CS6,"CS6")
-#endif
-#ifdef CS7
-  TERMIOS_FLAG(c_cflag,CS7,"CS7")
-#endif
-#ifdef CS8
-  TERMIOS_FLAG(c_cflag,CS8,"CS8")
-#endif
 #ifdef CSTOPB
   TERMIOS_FLAG(c_cflag,CSTOPB,"CSTOPB")
 #endif
@@ -167,3 +139,123 @@
 #ifdef PENDIN
   TERMIOS_FLAG(c_lflag,PENDIN,"PENDIN")
 #endif
+
+#endif
+
+#ifdef TERMIOS_SPEED
+
+#ifdef B0
+TERMIOS_SPEED(B0,0)
+#endif
+#ifdef B50
+TERMIOS_SPEED(B50,50)
+#endif
+#ifdef B75
+TERMIOS_SPEED(B75,75)
+#endif
+#ifdef B110
+TERMIOS_SPEED(B110,110)
+#endif
+#ifdef B134
+TERMIOS_SPEED(B134,134)
+#endif
+#ifdef B150
+TERMIOS_SPEED(B150,150)
+#endif
+#ifdef B200
+TERMIOS_SPEED(B200,200)
+#endif
+#ifdef B300
+TERMIOS_SPEED(B300,300)
+#endif
+#ifdef B600
+TERMIOS_SPEED(B600,600)
+#endif
+#ifdef B1200
+TERMIOS_SPEED(B1200,1200)
+#endif
+#ifdef B1800
+TERMIOS_SPEED(B1800,1800)
+#endif
+#ifdef B2400
+TERMIOS_SPEED(B2400,2400)
+#endif
+#ifdef B4800
+TERMIOS_SPEED(B4800,4800)
+#endif
+#ifdef B9600
+TERMIOS_SPEED(B9600,9600)
+#endif
+#ifdef B19200
+TERMIOS_SPEED(B19200,19200)
+#endif
+#ifdef B38400
+TERMIOS_SPEED(B38400,38400)
+#endif
+#ifdef B57600
+TERMIOS_SPEED(B57600,57600)
+#endif
+#ifdef B115200
+TERMIOS_SPEED(B115200,115200)
+#endif
+#ifdef B230400
+TERMIOS_SPEED(B230400,230400)
+#endif
+
+#endif
+
+#ifdef TERMIOS_CHAR
+
+#ifdef VINTR
+   TERMIOS_CHAR(VINTR,"VINTR")
+#endif
+#ifdef VQUIT
+   TERMIOS_CHAR(VQUIT,"VQUIT")
+#endif
+#ifdef VERASE
+   TERMIOS_CHAR(VERASE,"VERASE")
+#endif
+#ifdef VKILL
+   TERMIOS_CHAR(VKILL,"VKILL")
+#endif
+#ifdef VEOF
+   TERMIOS_CHAR(VEOF,"VEOF")
+#endif
+#ifdef VTIME
+   TERMIOS_CHAR(VTIME,"VTIME")
+#endif
+#ifdef VMIN
+   TERMIOS_CHAR(VMIN,"VMIN")
+#endif
+#ifdef VSWTC
+   TERMIOS_CHAR(VSWTC,"VSWTC")
+#endif
+#ifdef VSTART
+   TERMIOS_CHAR(VSTART,"VSTART")
+#endif
+#ifdef VSTOP
+   TERMIOS_CHAR(VSTOP,"VSTOP")
+#endif
+#ifdef VSUSP
+   TERMIOS_CHAR(VSUSP,"VSUSP")
+#endif
+#ifdef VEOL
+   TERMIOS_CHAR(VEOL,"VEOL")
+#endif
+#ifdef VREPRINT
+   TERMIOS_CHAR(VREPRINT,"VREPRINT")
+#endif
+#ifdef VDISCARD
+   TERMIOS_CHAR(VDISCARD,"VDISCARD")
+#endif
+#ifdef VWERASE
+   TERMIOS_CHAR(VWERASE,"VWERASE")
+#endif
+#ifdef VLNEXT
+   TERMIOS_CHAR(VLNEXT,"VLNEXT")
+#endif
+#ifdef VEOL2
+   TERMIOS_CHAR(VEOL2,"VEOL2")
+#endif
+
+#endif
diff --git a/src/modules/files/termios_speeds.h b/src/modules/files/termios_speeds.h
deleted file mode 100644
index ca9384204cf7e742178d00d13c442d44d73a1a6f..0000000000000000000000000000000000000000
--- a/src/modules/files/termios_speeds.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifdef B0
-TERMIOS_SPEED(B0,0)
-#endif
-#ifdef B50
-TERMIOS_SPEED(B50,50)
-#endif
-#ifdef B75
-TERMIOS_SPEED(B75,75)
-#endif
-#ifdef B110
-TERMIOS_SPEED(B110,110)
-#endif
-#ifdef B134
-TERMIOS_SPEED(B134,134)
-#endif
-#ifdef B150
-TERMIOS_SPEED(B150,150)
-#endif
-#ifdef B200
-TERMIOS_SPEED(B200,200)
-#endif
-#ifdef B300
-TERMIOS_SPEED(B300,300)
-#endif
-#ifdef B600
-TERMIOS_SPEED(B600,600)
-#endif
-#ifdef B1200
-TERMIOS_SPEED(B1200,1200)
-#endif
-#ifdef B1800
-TERMIOS_SPEED(B1800,1800)
-#endif
-#ifdef B2400
-TERMIOS_SPEED(B2400,2400)
-#endif
-#ifdef B4800
-TERMIOS_SPEED(B4800,4800)
-#endif
-#ifdef B9600
-TERMIOS_SPEED(B9600,9600)
-#endif
-#ifdef B19200
-TERMIOS_SPEED(B19200,19200)
-#endif
-#ifdef B38400
-TERMIOS_SPEED(B38400,38400)
-#endif
-#ifdef B57600
-TERMIOS_SPEED(B57600,57600)
-#endif
-#ifdef B115200
-TERMIOS_SPEED(B115200,115200)
-#endif
-#ifdef B230400
-TERMIOS_SPEED(B230400,230400)
-#endif