Browse Source

Fix termios handling. Now synced with behavior of GNU libc.
-Erik

Eric Andersen 23 years ago
parent
commit
6fce1235be

+ 97 - 23
include/termios.h

@@ -1,33 +1,107 @@
-#ifndef __TERMIOS_H
-#define __TERMIOS_H
+/* Copyright (C) 1991, 92, 93, 94, 96, 97, 98 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+ *	POSIX Standard: 7.1-2 General Terminal Interface	<termios.h>
+ */
+
+#ifndef	_TERMIOS_H
+#define	_TERMIOS_H	1
 
 #include <features.h>
-#include <sys/types.h>
-#include <sys/termios.h>
-#include <asm/termbits.h>
+#ifdef __USE_UNIX98
+/* We need `pid_t'.  */
+# include <bits/types.h>
+# ifndef pid_t
+typedef __pid_t pid_t;
+#  define pid_t pid_t
+# endif
+#endif
 
-extern speed_t cfgetispeed __P ((struct termios *__termios_p));
-extern speed_t cfgetospeed __P ((struct termios *__termios_p));
-extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed));
+__BEGIN_DECLS
+
+/* Get the system-dependent definitions of `struct termios', `tcflag_t',
+   `cc_t', `speed_t', and all the macros specifying the flag bits.  */
+#include <bits/termios.h>
+
+#ifdef __USE_BSD
+/* Compare a character C to a value VAL from the `c_cc' array in a
+   `struct termios'.  If VAL is _POSIX_VDISABLE, no character can match it.  */
+# define CCEQ(val, c)	((c) == (val) && (val) != _POSIX_VDISABLE)
+#endif
+
+/* Return the output baud rate stored in *TERMIOS_P.  */
+extern speed_t cfgetospeed __P ((__const struct termios *__termios_p));
+
+/* Return the input baud rate stored in *TERMIOS_P.  */
+extern speed_t cfgetispeed __P ((__const struct termios *__termios_p));
+
+/* Set the output baud rate stored in *TERMIOS_P to SPEED.  */
 extern int cfsetospeed __P ((struct termios *__termios_p, speed_t __speed));
 
-extern int tcspeed_to_number __P ((speed_t __speed));
-extern speed_t tcspeed_from_number __P ((int number));
+/* Set the input baud rate stored in *TERMIOS_P to SPEED.  */
+extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed));
 
-extern int cfgetispeedn __P ((struct termios *__termios_p));
-extern int cfgetospeedn __P ((struct termios *__termios_p));
-extern int cfsetispeedn __P ((struct termios *__termios_p, int __speed));
-extern int cfsetospeedn __P ((struct termios *__termios_p, int __speed));
+#ifdef	__USE_BSD
+/* Set both the input and output baud rates in *TERMIOS_OP to SPEED.  */
+extern int cfsetspeed __P ((struct termios *__termios_p, speed_t __speed));
+#endif
 
-extern void cfmakeraw  __P ((struct termios *__t));
 
-extern int tcsetattr __P ((int __fd, int __opt, struct termios *__termios_p));
-extern int tcgetattr __P ((int __fildes, struct termios *__termios_p));
-extern int tcdrain __P ((int __fildes));
-extern int tcflow __P ((int __fildes, int __action));
-extern int tcflush __P ((int __fildes, int __queue_selector));
-extern int tcsendbreak __P ((int __fildes, int __duration));
-extern pid_t tcgetpgrp __P ((int __fildes));
-extern int tcsetpgrp __P ((int __fildes, pid_t __pgrp_id));
+/* Put the state of FD into *TERMIOS_P.  */
+extern int tcgetattr __P ((int __fd, struct termios *__termios_p));
 
+/* Set the state of FD to *TERMIOS_P.
+   Values for OPTIONAL_ACTIONS (TCSA*) are in <bits/termios.h>.  */
+extern int tcsetattr __P ((int __fd, int __optional_actions,
+			   __const struct termios *__termios_p));
+
+
+#ifdef	__USE_BSD
+/* Set *TERMIOS_P to indicate raw mode.  */
+extern void cfmakeraw __P ((struct termios *__termios_p));
+#endif
+
+/* Send zero bits on FD.  */
+extern int tcsendbreak __P ((int __fd, int __duration));
+
+/* Wait for pending output to be written on FD.  */
+extern int tcdrain __P ((int __fd));
+
+/* Flush pending data on FD.
+   Values for QUEUE_SELECTOR (TC{I,O,IO}FLUSH) are in <bits/termios.h>.  */
+extern int tcflush __P ((int __fd, int __queue_selector));
+
+/* Suspend or restart transmission on FD.
+   Values for ACTION (TC[IO]{OFF,ON}) are in <bits/termios.h>.  */
+extern int tcflow __P ((int __fd, int __action));
+
+
+#ifdef __USE_UNIX98
+/* Get process group ID for session leader for controlling terminal FD.  */
+extern __pid_t tcgetsid __P ((int __fd));
 #endif
+
+
+#ifdef __USE_BSD
+# include <sys/ttydefaults.h>
+#endif
+
+__END_DECLS
+
+#endif /* termios.h  */

+ 212 - 0
libc/sysdeps/linux/arm/bits/termios.h

@@ -0,0 +1,212 @@
+/* termios type and macro definitions.  Linux version.
+   Copyright (C) 1993, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 32
+struct termios
+  {
+    tcflag_t c_iflag;		/* input mode flags */
+    tcflag_t c_oflag;		/* output mode flags */
+    tcflag_t c_cflag;		/* control mode flags */
+    tcflag_t c_lflag;		/* local mode flags */
+    cc_t c_line;			/* line discipline */
+    cc_t c_cc[NCCS];		/* control characters */
+    speed_t c_ispeed;		/* input speed */
+    speed_t c_ospeed;		/* output speed */
+  };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY	0000400
+# define   NL0	0000000
+# define   NL1	0000400
+# define CRDLY	0003000
+# define   CR0	0000000
+# define   CR1	0001000
+# define   CR2	0002000
+# define   CR3	0003000
+# define TABDLY	0014000
+# define   TAB0	0000000
+# define   TAB1	0004000
+# define   TAB2	0010000
+# define   TAB3	0014000
+# define BSDLY	0020000
+# define   BS0	0000000
+# define   BS1	0020000
+# define FFDLY	0100000
+# define   FF0	0000000
+# define   FF1	0100000
+#endif
+
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+
+#ifdef __USE_MISC
+# define XTABS	0014000
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD	0010017
+#endif
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+#endif
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#ifdef __USE_MISC
+# define CBAUDEX 0010000
+#endif
+#define  B57600   0010001
+#define  B115200  0010002
+#define  B230400  0010003
+#define  B460800  0010004
+#define  B500000  0010005
+#define  B576000  0010006
+#define  B921600  0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#ifdef __USE_MISC
+# define CIBAUD	  002003600000		/* input baud rate (not used) */
+# define CRTSCTS  020000000000		/* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE	0000004
+#endif
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#ifdef __USE_MISC
+# define ECHOCTL 0001000
+# define ECHOPRT 0002000
+# define ECHOKE	 0004000
+# define FLUSHO	 0010000
+# define PENDIN	 0040000
+#endif
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+
+#define _IOT_termios /* Hurd ioctl type field.  */ \
+  _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2)

+ 3 - 3
libc/sysdeps/linux/common/syscalls.c

@@ -966,15 +966,15 @@ _syscall2(int,flock,int,fd, int,operation);
 #ifdef L_writev
 #include <sys/uio.h>
 _syscall3(ssize_t, writev, int, filedes, const struct iovec *, vector, int,
-
 		  count);
 #endif
 
 //#define __NR_getsid           147
 #ifdef L_getsid
-SYSCALL__(getsid, 1)
-	ret
+#include <unistd.h>
+_syscall1(pid_t, getsid, pid_t, pid);
 #endif
+
 //#define __NR_fdatasync        148
 #ifdef L_fdatasync
 	SYSCALL__(fdatasync, 1)

+ 212 - 0
libc/sysdeps/linux/i386/bits/termios.h

@@ -0,0 +1,212 @@
+/* termios type and macro definitions.  Linux version.
+   Copyright (C) 1993, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios.h> directly; use <termios.h> instead."
+#endif
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 32
+struct termios
+  {
+    tcflag_t c_iflag;		/* input mode flags */
+    tcflag_t c_oflag;		/* output mode flags */
+    tcflag_t c_cflag;		/* control mode flags */
+    tcflag_t c_lflag;		/* local mode flags */
+    cc_t c_line;			/* line discipline */
+    cc_t c_cc[NCCS];		/* control characters */
+    speed_t c_ispeed;		/* input speed */
+    speed_t c_ospeed;		/* output speed */
+  };
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#if defined __USE_MISC || defined __USE_XOPEN
+# define NLDLY	0000400
+# define   NL0	0000000
+# define   NL1	0000400
+# define CRDLY	0003000
+# define   CR0	0000000
+# define   CR1	0001000
+# define   CR2	0002000
+# define   CR3	0003000
+# define TABDLY	0014000
+# define   TAB0	0000000
+# define   TAB1	0004000
+# define   TAB2	0010000
+# define   TAB3	0014000
+# define BSDLY	0020000
+# define   BS0	0000000
+# define   BS1	0020000
+# define FFDLY	0100000
+# define   FF0	0000000
+# define   FF1	0100000
+#endif
+
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+
+#ifdef __USE_MISC
+# define XTABS	0014000
+#endif
+
+/* c_cflag bit meaning */
+#ifdef __USE_MISC
+# define CBAUD	0010017
+#endif
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#ifdef __USE_MISC
+# define EXTA B19200
+# define EXTB B38400
+#endif
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#ifdef __USE_MISC
+# define CBAUDEX 0010000
+#endif
+#define  B57600   0010001
+#define  B115200  0010002
+#define  B230400  0010003
+#define  B460800  0010004
+#define  B500000  0010005
+#define  B576000  0010006
+#define  B921600  0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#ifdef __USE_MISC
+# define CIBAUD	  002003600000		/* input baud rate (not used) */
+# define CRTSCTS  020000000000		/* flow control */
+#endif
+
+/* c_lflag bits */
+#define ISIG	0000001
+#define ICANON	0000002
+#if defined __USE_MISC || defined __USE_XOPEN
+# define XCASE	0000004
+#endif
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#ifdef __USE_MISC
+# define ECHOCTL 0001000
+# define ECHOPRT 0002000
+# define ECHOKE	 0004000
+# define FLUSHO	 0010000
+# define PENDIN	 0040000
+#endif
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+
+#define _IOT_termios /* Hurd ioctl type field.  */ \
+  _IOT (_IOTS (cflag_t), 4, _IOTS (cc_t), NCCS, _IOTS (speed_t), 2)

+ 5 - 4
libc/termios/Makefile

@@ -25,11 +25,12 @@ include $(TOPDIR)Rules.mak
 LIBC=$(TOPDIR)libc.a
 
 MSRC=termios.c
-MOBJ=tcsetattr.o tcgetattr.o tcdrain.o tcflow.o tcflush.o tcsendbreak.o	\
-     tcsetpgrp.o tcgetpgrp.o isatty.o cfgetospeed.o cfgetispeed.o cfsetospeed.o \
-     cfsetispeed.o cfmakeraw.o
+MOBJ= tcdrain.o tcflow.o tcflush.o tcsendbreak.o tcsetpgrp.o tcgetpgrp.o \
+	isatty.o cfgetospeed.o cfgetispeed.o cfsetospeed.o cfsetispeed.o \
+	cfmakeraw.o cfsetspeed.o
 
-CSRC=ttyname.c
+
+CSRC=tcgetattr.c tcgetsid.c tcsetattr.c ttyname.c
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 OBJS=$(MOBJ) $(COBJS)
 

+ 35 - 0
libc/termios/kernel_termios.h

@@ -0,0 +1,35 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _KERNEL_TERMIOS_H
+#define _KERNEL_TERMIOS_H 1
+/* The following corresponds to the values from the Linux 2.1.20 kernel.  */
+
+#define __KERNEL_NCCS 19
+
+struct __kernel_termios
+  {
+    tcflag_t c_iflag;		/* input mode flags */
+    tcflag_t c_oflag;		/* output mode flags */
+    tcflag_t c_cflag;		/* control mode flags */
+    tcflag_t c_lflag;		/* local mode flags */
+    cc_t c_line;		/* line discipline */
+    cc_t c_cc[__KERNEL_NCCS];	/* control characters */
+  };
+
+#endif /* kernel_termios.h */

+ 67 - 0
libc/termios/tcgetattr.c

@@ -0,0 +1,67 @@
+/* Copyright (C) 1992, 1995, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+/* The difference here is that the termios structure used in the
+   kernel is not the same as we use in the libc.  Therefore we must
+   translate it here.  */
+#include "kernel_termios.h"
+
+/* Put the state of FD into *TERMIOS_P.  */
+int tcgetattr ( int fd, struct termios *termios_p)
+{
+  struct __kernel_termios k_termios;
+  int retval;
+
+  retval = ioctl (fd, TCGETS, &k_termios);
+
+  termios_p->c_iflag = k_termios.c_iflag;
+  termios_p->c_oflag = k_termios.c_oflag;
+  termios_p->c_cflag = k_termios.c_cflag;
+  termios_p->c_lflag = k_termios.c_lflag;
+  termios_p->c_line = k_termios.c_line;
+#ifdef _HAVE_C_ISPEED
+  termios_p->c_ispeed = k_termios.c_ispeed;
+#endif
+#ifdef _HAVE_C_OSPEED
+  termios_p->c_ospeed = k_termios.c_ospeed;
+#endif
+  if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0
+      || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1)
+    memset ( (memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0],
+		       __KERNEL_NCCS * sizeof (cc_t)) + (__KERNEL_NCCS * sizeof (cc_t))) , 
+	    _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t));
+  else
+    {
+      size_t cnt;
+
+      memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0],
+	      __KERNEL_NCCS * sizeof (cc_t));
+
+      for (cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt)
+	termios_p->c_cc[cnt] = _POSIX_VDISABLE;
+    }
+
+  return retval;
+}
+

+ 64 - 0
libc/termios/tcgetsid.c

@@ -0,0 +1,64 @@
+/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#define __USE_XOPEN_EXTENDED
+#include <unistd.h>
+
+
+/* Return the session ID of FD.  */
+pid_t tcgetsid (int fd)
+{
+    pid_t pgrp;
+    pid_t sid;
+#ifdef TIOCGSID
+    static int tiocgsid_does_not_work;
+
+    if (! tiocgsid_does_not_work)
+    {
+	int serrno = errno;
+	int sid;
+
+	if (ioctl (fd, TIOCGSID, &sid) < 0)
+	{
+	    if (errno == EINVAL)
+	    {
+		tiocgsid_does_not_work = 1;
+		errno=serrno;
+	    }
+	    else
+		return (pid_t) -1;
+	}
+	else
+	    return (pid_t) sid;
+    }
+#endif
+
+    pgrp = tcgetpgrp (fd);
+    if (pgrp == -1)
+	return (pid_t) -1;
+
+    sid = getsid (pgrp);
+    if (sid == -1 && errno == ESRCH)
+	errno=ENOTTY;
+
+    return sid;
+}

+ 120 - 0
libc/termios/tcsetattr.c

@@ -0,0 +1,120 @@
+/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <string.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+/* The difference here is that the termios structure used in the
+   kernel is not the same as we use in the libc.  Therefore we must
+   translate it here.  */
+#include <kernel_termios.h>
+
+
+/* This is a gross hack around a kernel bug.  If the cfsetispeed functions
+   is called with the SPEED argument set to zero this means use the same
+   speed as for output.  But we don't have independent input and output
+   speeds and therefore cannot record this.
+
+   We use an unused bit in the `c_iflag' field to keep track of this
+   use of `cfsetispeed'.  The value here must correspond to the one used
+   in `speed.c'.  */
+#if !defined _HAVE_C_ISPEED || !defined _HAVE_C_OSPEED
+# define IBAUD0	020000000000
+#else
+/* If we have separate values for input and output speed don't bother
+   with this.  Define the value as zero so the compiler sees we don't
+   have to do the AND below.  */
+# define IBAUD0	0
+#endif
+
+
+/* Set the state of FD to *TERMIOS_P.  */
+int
+tcsetattr (fd, optional_actions, termios_p)
+     int fd;
+     int optional_actions;
+     const struct termios *termios_p;
+{
+  struct __kernel_termios k_termios;
+  unsigned long int cmd;
+  int retval;
+
+  switch (optional_actions)
+    {
+    case TCSANOW:
+      cmd = TCSETS;
+      break;
+    case TCSADRAIN:
+      cmd = TCSETSW;
+      break;
+    case TCSAFLUSH:
+      cmd = TCSETSF;
+      break;
+    default:
+      errno=EINVAL;
+      return -1;
+    }
+
+  k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0;
+  k_termios.c_oflag = termios_p->c_oflag;
+  k_termios.c_cflag = termios_p->c_cflag;
+  k_termios.c_lflag = termios_p->c_lflag;
+  k_termios.c_line = termios_p->c_line;
+#ifdef _HAVE_C_ISPEED
+  k_termios.c_ispeed = termios_p->c_ispeed;
+#endif
+#ifdef _HAVE_C_OSPEED
+  k_termios.c_ospeed = termios_p->c_ospeed;
+#endif
+  memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
+	  __KERNEL_NCCS * sizeof (cc_t));
+
+  retval = ioctl (fd, cmd, &k_termios);
+
+  if (retval == 0 && cmd == TCSETS)
+    {
+      /* The Linux kernel has a bug which silently ignore the invalid
+	 c_cflag on pty. We have to check it here. */
+      int save = errno;
+      retval = ioctl (fd, TCGETS, &k_termios);
+      if (retval)
+	{
+	  /* We cannot verify if the setting is ok. We don't return
+	     an error (?). */
+	  errno=save;
+	  retval = 0;
+	}
+      else if ((termios_p->c_cflag & (PARENB | CREAD))
+	       != (k_termios.c_cflag & (PARENB | CREAD))
+	       || ((termios_p->c_cflag & CSIZE)
+		   && ((termios_p->c_cflag & CSIZE)
+		       != (k_termios.c_cflag & CSIZE))))
+	{
+	  /* It looks like the Linux kernel silently changed the
+	     PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
+	     error. */
+	  errno=EINVAL;
+	  retval = -1;
+	}
+    }
+
+  return retval;
+}

+ 173 - 229
libc/termios/termios.c

@@ -1,12 +1,28 @@
-/* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> This
- * file is part of the Linux-8086 C library and is distributed under the
- * GNU Library General Public License.
+/* Copyright (C) 1992, 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  
+ 
+
+   About the only thing remaining here fromthe original Linux-8086 C library
+   version by Robert de Bath <robert@mayday.compulink.co.uk>, is the general
+   layout.  All else has been recently stolen from GNU libc, since that was
+   much more current.
  */
 
-/* Note: This is based loosely on the Glib termios routines. */
-
-#ifndef __MSDOS__
-
 #include <errno.h>
 #include <stddef.h>
 #include <sys/ioctl.h>
@@ -14,82 +30,43 @@
 #include <unistd.h>
 
 #ifdef L_isatty
+/* Return 1 if FD is a terminal, 0 if not.  */
 int isatty(int fd)
 {
-	struct termios term;
-	int rv, err = errno;
-
-	rv = (ioctl(fd, TCGETS, &term) == 0);
-	if (rv == 0 && errno == ENOSYS)
-		rv = (fd < 3);
-	errno = err;
-	return rv;
-}
-#endif
+  struct termios term;
 
-#ifdef L_tcgetattr
-int tcgetattr(fd, term)
-int fd;
-struct termios *term;
-{
-	return ioctl(fd, TCGETS, term);
-}
-#endif
-
-#ifdef L_tcsetattr
-int tcsetattr(fildes, optional_actions, termios_p)
-int fildes;
-int optional_actions;
-struct termios *termios_p;
-{
-	switch (optional_actions) {
-	case TCSANOW:
-		return ioctl(fildes, TCSETS, termios_p);
-	case TCSADRAIN:
-		return ioctl(fildes, TCSETSW, termios_p);
-	case TCSAFLUSH:
-		return ioctl(fildes, TCSETSF, termios_p);
-	default:
-		errno = EINVAL;
-		return -1;
-	}
+  return tcgetattr(fd, &term) == 0;
 }
 #endif
 
 #ifdef L_tcdrain
 /* Wait for pending output to be written on FD.  */
-int tcdrain(fd)
-int fd;
+int tcdrain (int fd)
 {
-	/* With an argument of 1, TCSBRK just waits for output to drain.  */
-	return ioctl(fd, TCSBRK, 1);
+      /* With an argument of 1, TCSBRK waits for the output to drain.  */
+      return ioctl(fd, TCSBRK, 1);
 }
 #endif
 
 #ifdef L_tcflow
-int tcflow(fd, action)
-int fd;
-int action;
+/* Suspend or restart transmission on FD.  */
+int tcflow ( int fd, int action)
 {
-	return ioctl(fd, TCXONC, action);
+      return ioctl(fd, TCXONC, action);
 }
 #endif
 
 #ifdef L_tcflush
 /* Flush pending data on FD.  */
-int tcflush(fd, queue_selector)
-int fd;
-int queue_selector;
+int tcflush ( int fd, int queue_selector)
 {
-	return ioctl(fd, TCFLSH, queue_selector);
+      return ioctl(fd, TCFLSH, queue_selector);
 }
 #endif
 
 #ifdef L_tcsendbreak
 /* Send zero bits on FD.  */
-int tcsendbreak(fd, duration)
-int fd;
-int duration;
+int tcsendbreak( int fd, int duration)
 {
 	/*
 	 * The break lasts 0.25 to 0.5 seconds if DURATION is zero, and an
@@ -111,260 +88,227 @@ int duration;
 
 #ifdef L_tcsetpgrp
 /* Set the foreground process group ID of FD set PGRP_ID.  */
-int tcsetpgrp(fd, pgrp_id)
-int fd;
-pid_t pgrp_id;
+int tcsetpgrp ( int fd, pid_t pgrp_id)
 {
-	return ioctl(fd, TIOCSPGRP, &pgrp_id);
+      return ioctl (fd, TIOCSPGRP, &pgrp_id);
 }
 #endif
 
 #ifdef L_tcgetpgrp
 /* Return the foreground process group ID of FD.  */
-pid_t tcgetpgrp(fd)
-int fd;
+pid_t tcgetpgrp ( int fd)
 {
-	int pgrp;
+    int pgrp;
 
-	if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
-		return (pid_t) - 1;
-	return (pid_t) pgrp;
+    if (ioctl (fd, TIOCGPGRP, &pgrp) < 0)
+	return (pid_t) -1;
+    return (pid_t) pgrp;
 }
 #endif
 
+/* This is a gross hack around a kernel bug.  If the cfsetispeed functions is
+ * called with the SPEED argument set to zero this means use the same speed as
+ * for output.  But we don't have independent input and output speeds and
+ * therefore cannot record this.
+ *
+ * We use an unused bit in the `c_iflag' field to keep track of this use of
+ * `cfsetispeed'.  The value here must correspond to the one used in
+ * `tcsetattr.c'.  */
+#define IBAUD0  020000000000
+
 #ifdef L_cfgetospeed
-speed_t cfgetospeed(tp)
-struct termios *tp;
+/* Return the output baud rate stored in *TERMIOS_P.  */
+speed_t cfgetospeed ( const struct termios *termios_p)
 {
-	return (tp->c_cflag & CBAUD);
+      return termios_p->c_cflag & (CBAUD | CBAUDEX);
 }
 #endif
 
 #ifdef L_cfgetispeed
-speed_t cfgetispeed(tp)
-struct termios *tp;
+
+/* Return the input baud rate stored in *TERMIOS_P.
+ * Although for Linux there is no difference between input and output
+ * speed, the numerical 0 is a special case for the input baud rate. It
+ * should set the input baud rate to the output baud rate. */
+speed_t cfgetispeed (const struct termios *termios_p)
 {
-	return (tp->c_cflag & CBAUD);
+    return ((termios_p->c_iflag & IBAUD0)
+	    ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX));
 }
 #endif
 
 #ifdef L_cfsetospeed
-int cfsetospeed(tp, speed)
-struct termios *tp;
-speed_t speed;
+/* Set the output baud rate stored in *TERMIOS_P to SPEED.  */
+int cfsetospeed  (struct termios *termios_p, speed_t speed)
 {
-#ifdef CBAUDEX
-	if ((speed & ~CBAUD) ||
-		((speed & CBAUDEX) && (speed < B57600 || speed > B115200)))
-		return 0;
-#else
-	if (speed & ~CBAUD)
-		return 0;
-#endif
-	tp->c_cflag &= ~CBAUD;
-	tp->c_cflag |= speed;
+    if ((speed & ~CBAUD) != 0
+	    && (speed < B57600 || speed > B460800))
+    {
+	errno=EINVAL;
+	return -1;
+    }
 
-	return 0;
+    termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
+    termios_p->c_cflag |= speed;
+
+    return 0;
 }
 #endif
 
 #ifdef L_cfsetispeed
-int cfsetispeed(tp, speed)
-struct termios *tp;
-speed_t speed;
+/* Set the input baud rate stored in *TERMIOS_P to SPEED.
+ *    Although for Linux there is no difference between input and output
+ *       speed, the numerical 0 is a special case for the input baud rate.  It
+ *          should set the input baud rate to the output baud rate.  */
+int cfsetispeed ( struct termios *termios_p, speed_t speed)
 {
-	return cfsetospeed(tp, speed);
+    if ((speed & ~CBAUD) != 0
+	    && (speed < B57600 || speed > B460800))
+    {
+	errno=EINVAL;
+	return -1;
+    }
+
+    if (speed == 0)
+	termios_p->c_iflag |= IBAUD0;
+    else
+    {
+	termios_p->c_iflag &= ~IBAUD0;
+	termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
+	termios_p->c_cflag |= speed;
+    }
+
+    return 0;
 }
 #endif
 
-#if 0
-
-/* Not POSIX standard, not worth the bother to keep it up */
-
 #ifdef L_tcspeed
-static struct {
-	int number;
-	speed_t code;
-} tcspeeds[] = {
+struct speed_struct
+{
+  speed_t value;
+  speed_t internal;
+};
+
+static const struct speed_struct speeds[] =
+  {
+#ifdef B0
+    { 0, B0 },
+#endif
 #ifdef B50
-	{
-	50, B50},
+    { 50, B50 },
 #endif
 #ifdef B75
-	{
-	75, B75},
+    { 75, B75 },
 #endif
 #ifdef B110
-	{
-	110, B110},
+    { 110, B110 },
 #endif
 #ifdef B134
-	{
-	134, B134},
+    { 134, B134 },
 #endif
 #ifdef B150
-	{
-	150, B150},
+    { 150, B150 },
 #endif
 #ifdef B200
-	{
-	200, B200},
+    { 200, B200 },
 #endif
 #ifdef B300
-	{
-	300, B300},
+    { 300, B300 },
 #endif
 #ifdef B600
-	{
-	600, B600},
+    { 600, B600 },
 #endif
 #ifdef B1200
-	{
-	1200, B1200},
+    { 1200, B1200 },
+#endif
+#ifdef B1200
+    { 1200, B1200 },
 #endif
 #ifdef B1800
-	{
-	1800, B1800},
+    { 1800, B1800 },
 #endif
 #ifdef B2400
-	{
-	2400, B2400},
+    { 2400, B2400 },
 #endif
 #ifdef B4800
-	{
-	4800, B4800},
+    { 4800, B4800 },
 #endif
 #ifdef B9600
-	{
-	9600, B9600},
+    { 9600, B9600 },
 #endif
 #ifdef B19200
-	{
-	19200, B19200},
+    { 19200, B19200 },
 #endif
 #ifdef B38400
-	{
-	38400, B38400},
+    { 38400, B38400 },
 #endif
 #ifdef B57600
-	{
-	57600, B57600},
+    { 57600, B57600 },
+#endif
+#ifdef B76800
+    { 76800, B76800 },
 #endif
 #ifdef B115200
-	{
-	115200, B115200},
+    { 115200, B115200 },
+#endif
+#ifdef B153600
+    { 153600, B153600 },
 #endif
 #ifdef B230400
-	{
-	230400, B230400},
+    { 230400, B230400 },
 #endif
-#ifdef B460800
-	{
-	460800, B460800},
+#ifdef B307200
+    { 307200, B307200 },
 #endif
-#ifdef B0
-	{
-	0, B0},
+#ifdef B460800
+    { 460800, B460800 },
 #endif
-	{
-	0, 0}
-};
-
-int tcspeed_to_number(code)
-speed_t code;
-{
-	int i;
+  };
 
-	code &= CBAUD;
-	for (i = 0; tcspeeds[i].code; i++)
-		if (tcspeeds[i].code == code)
-			return tcspeeds[i].number;
-	return 0;
-}
 
-speed_t tcspeed_from_number(number)
-int number;
+/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED.  */
+int cfsetspeed (struct termios *termios_p, speed_t speed)
 {
-	int i;
-
-	for (i = 0; tcspeeds[i].code; i++)
-		if (tcspeeds[i].number == number)
-			return tcspeeds[i].code;
-	return B0;
-}
-#endif
+  size_t cnt;
 
-#ifdef L_cfgetospeedn
-int cfgetospeedn(tp)
-struct termios *tp;
-{
-	return tcspeed_to_number(cfgetospeed(tp));
-}
-#endif
-
-#ifdef L_cfgetispeedn
-int cfgetispeedn(tp)
-struct termios *tp;
-{
-	return tcspeed_to_number(cfgetispeed(tp));
-}
-#endif
+  for (cnt = 0; cnt < sizeof (speeds) / sizeof (speeds[0]); ++cnt)
+    if (speed == speeds[cnt].internal)
+      {
+	cfsetispeed (termios_p, speed);
+	cfsetospeed (termios_p, speed);
+	return 0;
+      }
+    else if (speed == speeds[cnt].value)
+      {
+	cfsetispeed (termios_p, speeds[cnt].internal);
+	cfsetospeed (termios_p, speeds[cnt].internal);
+	return 0;
+      }
 
-#ifdef L_cfsetospeedn
-int cfsetospeedn(tp, speed)
-struct termios *tp;
-int speed;
-{
-	return cfsetospeed(tp, tcspeed_from_number(speed));
-}
-#endif
+  __set_errno (EINVAL);
 
-#ifdef L_cfsetispeedn
-int cfsetispeedn(tp, speed)
-struct termios *tp;
-int speed;
-{
-	return cfsetispeedn(tp, tcspeed_from_number(speed));
+  return -1;
 }
 #endif
 
-#endif
-
-/* From linux libc-4.6.27 again */
 #ifdef L_cfmakeraw
-/* Copyright (C) 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.*/
+/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+*/
+#include <termios.h>
 
-void cfmakeraw(t)
-struct termios *t;
+/* Set *T to indicate raw mode.  */
+void
+cfmakeraw (t)
+     struct termios *t;
 {
-/* I changed it to the current form according to the suggestions 
- * from Bruce Evans. Thanks Bruce. Please report the problems to
- * H.J. Lu (hlu@eecs.wsu.edu).
- */
-
-/*
- * I took out the bits commented out by #if 1...#else    - RHP
- */
-
-	/*  VMIN = 0 means non-blocking for Linux */
-	t->c_cc[VMIN] = 1;
-	t->c_cc[VTIME] = 1;
-	/* clear some bits with &= ~(bits), set others with |= */
-	t->c_cflag &= ~(CSIZE | PARENB | CSTOPB);
-	t->c_cflag |= (CS8 | HUPCL | CREAD);
-	t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP);
-	t->c_iflag &= ~(INLCR | IGNCR | ICRNL | IXON | IXOFF);
-	t->c_iflag |= (BRKINT | IGNPAR);
-	t->c_oflag &=
-		~(OPOST | OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL);
-	t->c_oflag &= ~(NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
-	t->c_oflag |= (ONLCR | NL0 | CR0 | TAB3 | BS0 | VT0 | FF0);
-	t->c_lflag &=
-		~(ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL);
-	t->c_lflag &= ~(NOFLSH | XCASE);
-	t->c_lflag &= ~(ECHOPRT | ECHOCTL | ECHOKE);
+  t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+  t->c_oflag &= ~OPOST;
+  t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+  t->c_cflag &= ~(CSIZE|PARENB);
+  t->c_cflag |= CS8;
+  t->c_cc[VMIN] = 1;		/* read returns when one char is available.  */
+  t->c_cc[VTIME] = 0;
 }
 #endif
 
-#endif