summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-01-15 18:16:14 +0000
committerEric Andersen <andersen@codepoet.org>2001-01-15 18:16:14 +0000
commit6fce1235bea41b65a0b7a978c65b908c736365d4 (patch)
tree87f187b31b047b77f09d7581affbe2a032b36ced /libc
parent5d83a25c29718b926ed547abf9131ffbbd35bc95 (diff)
Fix termios handling. Now synced with behavior of GNU libc.
-Erik
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/arm/bits/termios.h212
-rw-r--r--libc/sysdeps/linux/common/syscalls.c6
-rw-r--r--libc/sysdeps/linux/i386/bits/termios.h212
-rw-r--r--libc/termios/Makefile9
-rw-r--r--libc/termios/kernel_termios.h35
-rw-r--r--libc/termios/tcgetattr.c67
-rw-r--r--libc/termios/tcgetsid.c64
-rw-r--r--libc/termios/tcsetattr.c120
-rw-r--r--libc/termios/termios.c402
9 files changed, 891 insertions, 236 deletions
diff --git a/libc/sysdeps/linux/arm/bits/termios.h b/libc/sysdeps/linux/arm/bits/termios.h
new file mode 100644
index 000000000..a5ba1d258
--- /dev/null
+++ b/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)
diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c
index e726ba7fc..534f3779c 100644
--- a/libc/sysdeps/linux/common/syscalls.c
+++ b/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)
diff --git a/libc/sysdeps/linux/i386/bits/termios.h b/libc/sysdeps/linux/i386/bits/termios.h
new file mode 100644
index 000000000..a5ba1d258
--- /dev/null
+++ b/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)
diff --git a/libc/termios/Makefile b/libc/termios/Makefile
index f90c5922a..8b1f9e2ea 100644
--- a/libc/termios/Makefile
+++ b/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)
diff --git a/libc/termios/kernel_termios.h b/libc/termios/kernel_termios.h
new file mode 100644
index 000000000..09504cc97
--- /dev/null
+++ b/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 */
diff --git a/libc/termios/tcgetattr.c b/libc/termios/tcgetattr.c
new file mode 100644
index 000000000..957b5b0c1
--- /dev/null
+++ b/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;
+}
+
diff --git a/libc/termios/tcgetsid.c b/libc/termios/tcgetsid.c
new file mode 100644
index 000000000..35e1c95eb
--- /dev/null
+++ b/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;
+}
diff --git a/libc/termios/tcsetattr.c b/libc/termios/tcsetattr.c
new file mode 100644
index 000000000..30ea46f4c
--- /dev/null
+++ b/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;
+}
diff --git a/libc/termios/termios.c b/libc/termios/termios.c
index 6781f32fd..9bfcf1171 100644
--- a/libc/termios/termios.c
+++ b/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