From bd051b4dfb93b0f57c99ac865343ea63c66b3cde Mon Sep 17 00:00:00 2001
From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org>
Date: Thu, 17 Dec 1998 01:48:31 +0100
Subject: [PATCH] termios support added

Rev: src/modules/files/Makefile.in:1.7
Rev: src/modules/files/acconfig.h:1.11
Rev: src/modules/files/configure.in:1.61
Rev: src/modules/files/file.c:1.130
Rev: src/modules/files/file_functions.h:1.7
Rev: src/modules/files/termios.c:1.1
Rev: src/modules/files/termios_flags.h:1.1
Rev: src/modules/files/termios_speeds.h:1.1
---
 .gitattributes                     |   1 +
 src/modules/files/Makefile.in      |   4 +-
 src/modules/files/acconfig.h       |   5 +-
 src/modules/files/configure.in     |   7 +-
 src/modules/files/file.c           |  11 +-
 src/modules/files/file_functions.h |  10 ++
 src/modules/files/termios.c        | 196 +++++++++++++++++++++++++++++
 src/modules/files/termios_flags.h  | 169 +++++++++++++++++++++++++
 src/modules/files/termios_speeds.h |  57 +++++++++
 9 files changed, 454 insertions(+), 6 deletions(-)
 create mode 100644 src/modules/files/termios.c
 create mode 100644 src/modules/files/termios_flags.h
 create mode 100644 src/modules/files/termios_speeds.h

diff --git a/.gitattributes b/.gitattributes
index 2b2b6b1593..0c9815343d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -336,6 +336,7 @@ testfont binary
 /src/modules/files/file.h foreign_ident
 /src/modules/files/socket.c foreign_ident
 /src/modules/files/socktest.pike foreign_ident
+/src/modules/files/termios.c foreign_ident
 /src/modules/math/Makefile.in foreign_ident
 /src/modules/math/configure.in foreign_ident
 /src/modules/math/math.c foreign_ident
diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in
index ead1c056d9..670b9432f4 100644
--- a/src/modules/files/Makefile.in
+++ b/src/modules/files/Makefile.in
@@ -1,7 +1,7 @@
-# $Id: Makefile.in,v 1.6 1998/03/28 14:00:45 grubba Exp $
+# $Id: Makefile.in,v 1.7 1998/12/17 00:48:22 mirar Exp $
 SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../..:../..
-OBJS=file.o efuns.o socket.o
+OBJS=file.o efuns.o socket.o termios.o
 MODULE_LDFLAGS=@LIBS@
 MODULE_TESTS=local_tests
 
diff --git a/src/modules/files/acconfig.h b/src/modules/files/acconfig.h
index be8912dce8..d7c112172e 100644
--- a/src/modules/files/acconfig.h
+++ b/src/modules/files/acconfig.h
@@ -1,5 +1,5 @@
 /*
- * $Id: acconfig.h,v 1.10 1998/08/06 23:37:20 grubba Exp $
+ * $Id: acconfig.h,v 1.11 1998/12/17 00:48:24 mirar Exp $
  */
 
 #ifndef FILE_MACHINE_H
@@ -53,5 +53,8 @@
 /* Number of args to mkdir() */
 #define MKDIR_ARGS 2
 
+/* With termios */
+#undef WITH_TERMIOS 
+
 #endif
 
diff --git a/src/modules/files/configure.in b/src/modules/files/configure.in
index a55eef8dd1..afb44a174c 100644
--- a/src/modules/files/configure.in
+++ b/src/modules/files/configure.in
@@ -1,13 +1,16 @@
-# $Id: configure.in,v 1.60 1998/09/20 17:54:20 grubba Exp $
+# $Id: configure.in,v 1.61 1998/12/17 00:48:25 mirar Exp $
 AC_INIT(file.c)
 AC_CONFIG_HEADER(file_machine.h)
 
 AC_MODULE_INIT()
 
+AC_DEFINE(WITH_TERMIOS)
+
 AC_HAVE_HEADERS(sys/types.h arpa/inet.h sys/socketvar.h netinet/in.h poll.h sys/poll.h \
  sys/mount.h ustat.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/param.h \
  sys/socket.h sys/stream.h sys/protosw.h netdb.h sys/sysproto.h winsock.h \
- direct.h sys/wait.h process.h sys/file.h net/netdb.h limits.h unistd.h)
+ direct.h sys/wait.h process.h sys/file.h net/netdb.h limits.h unistd.h \
+ termios.h)
 AC_HEADER_DIRENT
 AC_CHECK_LIB(bind, __inet_ntoa)
 AC_CHECK_LIB(socket, socket)
diff --git a/src/modules/files/file.c b/src/modules/files/file.c
index b994bb6f52..e54b1131a8 100644
--- a/src/modules/files/file.c
+++ b/src/modules/files/file.c
@@ -5,7 +5,7 @@
 \*/
 
 #include "global.h"
-RCSID("$Id: file.c,v 1.129 1998/12/06 22:55:41 hubbe Exp $");
+RCSID("$Id: file.c,v 1.130 1998/12/17 00:48:26 mirar Exp $");
 #include "fdlib.h"
 #include "interpret.h"
 #include "svalue.h"
@@ -2311,6 +2311,15 @@ void check_static_file_data(struct callback *a, void *b, void *c)
 }
 #endif
 
+#if defined(WITH_TERMIOS) && defined(HAVE_TERMIOS_H)
+void file_tcgetattr(INT32 args);
+void file_tcsetattr(INT32 args);
+void file_tcsendbreak(INT32 args);
+void file_tcdrain(INT32 args);
+void file_tcflow(INT32 args);
+void file_tcgetpgrp(INT32 args);
+void file_tcsetpgrp(INT32 args);
+#endif
 
 void pike_module_init(void)
 {
diff --git a/src/modules/files/file_functions.h b/src/modules/files/file_functions.h
index 1682ce905b..8106a46f06 100644
--- a/src/modules/files/file_functions.h
+++ b/src/modules/files/file_functions.h
@@ -55,4 +55,14 @@
   FILE_FUNC("trylock",file_trylock,"function(void|int:object)")
 #endif
 
+#if defined(WITH_TERMIOS) && defined(HAVE_TERMIOS_H)
+   FILE_FUNC("tcgetattr",file_tcgetattr,"function(void:mapping)")
+   FILE_FUNC("tcsetattr",file_tcsetattr,"function(mapping,void|string:int)")
+/*    FILE_FUNC("tcsendbreak",file_tcsendbreak,"function(int:int)") */
+/*    FILE_FUNC("tcdrain",file_tcdrain,"function(void:int)") */
+/*    FILE_FUNC("tcflow",file_tcflow,"function(string:int)") */
+/*    FILE_FUNC("tcgetpgrp",file_tcgetpgrp,"function(void:int)") */
+/*    FILE_FUNC("tcsetpgrp",file_tcsetpgrp,"function(int:int)") */
+#endif
+
 #undef FILE_FUNC
diff --git a/src/modules/files/termios.c b/src/modules/files/termios.c
new file mode 100644
index 0000000000..bbeb36fa05
--- /dev/null
+++ b/src/modules/files/termios.c
@@ -0,0 +1,196 @@
+#include "global.h"
+RCSID("$Id: termios.c,v 1.1 1998/12/17 00:48:30 mirar Exp $");
+#include "file_machine.h"
+
+#if defined(WITH_TERMIOS) && defined(HAVE_TERMIOS_H)
+
+#include <termios.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "fdlib.h"
+#include "interpret.h"
+#include "mapping.h"
+#include "svalue.h"
+#include "stralloc.h"
+#include "operators.h"
+
+#include "file.h"
+
+
+/*
+**! method mapping tcgetattr()
+**! method int tcsetattr(mapping attr)
+**! method int tcsetattr(mapping attr,string when)
+**!	gets/sets term attributes
+**!
+**!	the returned value/the parameter is a mapping on the form
+**!	<pre>
+**!		"ispeed":baud rate
+**!		"ospeed":baud rate
+**!		flag:0|1
+**!		...
+**!	</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>
+**!
+**!	the argument 'when' to tcsetattr describes when the 
+**!	changes are to take effect:
+**!	"TCSANOW": the change occurs immediately (default);
+**!	"TCSADRAIN": the change occurs after all output has been written;
+**!	"TCSAFLUSH": the change occurs after all output has been written,
+**!	and empties input buffers.
+**!
+**!	returns 0 if failed.
+*/
+
+#undef THIS
+#define THIS ((struct my_file *)(fp->current_storage))
+#define FD (THIS->fd)
+#define ERRNO (THIS->my_errno)
+
+void file_tcgetattr(INT32 args)
+{
+   struct termios ti;
+   int n;
+
+   if(FD < 0)
+      error("File not open.\n");
+
+   pop_n_elems(args);
+
+   if (tcgetattr(FD,&ti)) /* error */
+   {
+      ERRNO=errno;
+      push_int(0);
+      return;
+   }
+
+   n=0;
+
+#define TERMIOS_FLAG(where,flag,sflag) \
+   push_text(sflag); \
+   push_int(!!(ti.where&flag)); \
+   n++; 
+
+#include "termios_flags.h"
+
+#undef TERMIOS_FLAG
+
+   push_text("ospeed");
+   switch (cfgetospeed(&ti))
+   {
+#define TERMIOS_SPEED(B,V) case B: push_int(V); break;
+#include "termios_speeds.h"
+      default: push_int(-1);
+   }
+   n++;
+
+   push_text("ispeed");
+   switch (cfgetispeed(&ti))
+   {
+#include "termios_speeds.h"
+#undef TERMIOS_SPEED
+      default: push_int(-1);
+   }
+   n++;
+
+   f_aggregate_mapping(n*2);
+}
+
+void file_tcsetattr(INT32 args)
+{
+   struct termios ti;
+   int optional_actions=TCSANOW;
+
+   if(FD < 0)
+      error("File not open.\n");
+
+   if (!args)
+      error("too few arguments to tcsetattr\n");
+
+
+   if (args>=2)
+   {
+      if (sp[-1].type!=T_STRING)
+	 error("illegal argument 2 to tcsetattr\n");
+	  
+      if (!strcmp(sp[-1].u.string->str,"TCSANOW"))
+	 optional_actions=TCSANOW;
+      else if (!strcmp(sp[-1].u.string->str,"TCSADRAIN"))
+	 optional_actions=TCSADRAIN;
+      else if (!strcmp(sp[-1].u.string->str,"TCSAFLUSH"))
+	 optional_actions=TCSAFLUSH;
+      else
+	 error("illegal argument 2 to tcsetattr\n");
+
+      pop_n_elems(args-1);
+   }
+
+   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;
+
+#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; \
+   pop_stack();
+
+#include "termios_flags.h"
+
+#undef TERMIOS_FLAG
+
+   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)
+   {
+#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");
+   }
+   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)
+   {
+#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");
+   }
+   cfsetispeed(&ti,sp[-1].u.integer);
+   pop_stack();
+   pop_stack();
+
+   pop_stack(); /* lose the mapping */
+   
+   push_int(!tcsetattr(FD,optional_actions,&ti));
+}
+
+
+/* end of termios stuff */
+#endif 
diff --git a/src/modules/files/termios_flags.h b/src/modules/files/termios_flags.h
new file mode 100644
index 0000000000..644157d15f
--- /dev/null
+++ b/src/modules/files/termios_flags.h
@@ -0,0 +1,169 @@
+#ifdef IGNBRK
+  TERMIOS_FLAG(c_iflag,IGNBRK,"IGNBRK")
+#endif
+#ifdef BRKINT
+  TERMIOS_FLAG(c_iflag,BRKINT,"BRKINT")
+#endif
+#ifdef IGNPAR
+  TERMIOS_FLAG(c_iflag,IGNPAR,"IGNPAR")
+#endif
+#ifdef PARMRK
+  TERMIOS_FLAG(c_iflag,PARMRK,"PARMRK")
+#endif
+#ifdef INPCK
+  TERMIOS_FLAG(c_iflag,INPCK,"INPCK")
+#endif
+#ifdef ISTRIP
+  TERMIOS_FLAG(c_iflag,ISTRIP,"ISTRIP")
+#endif
+#ifdef INLCR
+  TERMIOS_FLAG(c_iflag,INLCR,"INLCR")
+#endif
+#ifdef IGNCR
+  TERMIOS_FLAG(c_iflag,IGNCR,"IGNCR")
+#endif
+#ifdef ICRNL
+  TERMIOS_FLAG(c_iflag,ICRNL,"ICRNL")
+#endif
+#ifdef IUCLC
+  TERMIOS_FLAG(c_iflag,IUCLC,"IUCLC")
+#endif
+#ifdef IXON
+  TERMIOS_FLAG(c_iflag,IXON,"IXON")
+#endif
+#ifdef IXANY
+  TERMIOS_FLAG(c_iflag,IXANY,"IXANY")
+#endif
+#ifdef IXOFF
+  TERMIOS_FLAG(c_iflag,IXOFF,"IXOFF")
+#endif
+#ifdef IMAXBEL
+  TERMIOS_FLAG(c_iflag,IMAXBEL,"IMAXBEL")
+#endif
+
+#ifdef OPOST
+  TERMIOS_FLAG(c_oflag,OPOST,"OPOST")
+#endif
+#ifdef OLCUC
+  TERMIOS_FLAG(c_oflag,OLCUC,"OLCUC")
+#endif
+#ifdef ONLCR
+  TERMIOS_FLAG(c_oflag,ONLCR,"ONLCR")
+#endif
+#ifdef OCRNL
+  TERMIOS_FLAG(c_oflag,OCRNL,"OCRNL")
+#endif
+#ifdef ONOCR
+  TERMIOS_FLAG(c_oflag,ONOCR,"ONOCR")
+#endif
+#ifdef ONLRET
+  TERMIOS_FLAG(c_oflag,ONLRET,"ONLRET")
+#endif
+#ifdef OFILL
+  TERMIOS_FLAG(c_oflag,OFILL,"OFILL")
+#endif
+#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
+#ifdef ONOEOT
+  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
+#ifdef CREAD
+  TERMIOS_FLAG(c_cflag,CREAD,"CREAD")
+#endif
+#ifdef PARENB
+  TERMIOS_FLAG(c_cflag,PARENB,"PARENB")
+#endif
+#ifdef PARODD
+  TERMIOS_FLAG(c_cflag,PARODD,"PARODD")
+#endif
+#ifdef HUPCL
+  TERMIOS_FLAG(c_cflag,HUPCL,"HUPCL")
+#endif
+#ifdef CLOCAL
+  TERMIOS_FLAG(c_cflag,CLOCAL,"CLOCAL")
+#endif
+
+#ifdef CRTSCTS
+  TERMIOS_FLAG(c_cflag,CRTSCTS,"CRTSCTS")
+#endif
+
+#ifdef ISIG
+  TERMIOS_FLAG(c_lflag,ISIG,"ISIG")
+#endif
+#ifdef ICANON
+  TERMIOS_FLAG(c_lflag,ICANON,"ICANON")
+#endif
+#ifdef XCASE
+  TERMIOS_FLAG(c_lflag,XCASE,"XCASE")
+#endif
+#ifdef ECHO
+  TERMIOS_FLAG(c_lflag,ECHO,"ECHO")
+#endif
+#ifdef ECHOE
+  TERMIOS_FLAG(c_lflag,ECHOE,"ECHOE")
+#endif
+#ifdef ECHOK
+  TERMIOS_FLAG(c_lflag,ECHOK,"ECHOK")
+#endif
+#ifdef ECHONL
+  TERMIOS_FLAG(c_lflag,ECHONL,"ECHONL")
+#endif
+#ifdef ECHOCTL
+  TERMIOS_FLAG(c_lflag,ECHOCTL,"ECHOCTL")
+#endif
+#ifdef ECHOPRT
+  TERMIOS_FLAG(c_lflag,ECHOPRT,"ECHOPRT")
+#endif
+#ifdef ECHOKE
+  TERMIOS_FLAG(c_lflag,ECHOKE,"ECHOKE")
+#endif
+#ifdef FLUSHO
+  TERMIOS_FLAG(c_lflag,FLUSHO,"FLUSHO")
+#endif
+#ifdef NOFLSH
+  TERMIOS_FLAG(c_lflag,NOFLSH,"NOFLSH")
+#endif
+#ifdef TOSTOP
+  TERMIOS_FLAG(c_lflag,TOSTOP,"TOSTOP")
+#endif
+#ifdef PENDIN
+  TERMIOS_FLAG(c_lflag,PENDIN,"PENDIN")
+#endif
diff --git a/src/modules/files/termios_speeds.h b/src/modules/files/termios_speeds.h
new file mode 100644
index 0000000000..ca9384204c
--- /dev/null
+++ b/src/modules/files/termios_speeds.h
@@ -0,0 +1,57 @@
+#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
-- 
GitLab