From 4f735d8edbaac0690ead7c68783f2b36b9886888 Mon Sep 17 00:00:00 2001 From: Peter Wemm Date: Sun, 3 Mar 1996 19:07:50 +0000 Subject: [PATCH] Add support for the old-style Linux termio (not termios) TCGETA etc. Also, LINUX_POSIX_VDISABLE is \0, FreeBSD's is 0xff. Convert between them. This enables some more programs to run, including the Livingston Portmaster utilities (PMtools). Submitted by: Robert Sanders --- sys/alpha/linux/linux.h | 6 ++- sys/compat/linux/linux_ioctl.c | 74 +++++++++++++++++++++++++++++++++- sys/i386/linux/linux.h | 6 ++- sys/i386/linux/linux_ioctl.c | 74 +++++++++++++++++++++++++++++++++- 4 files changed, 152 insertions(+), 8 deletions(-) diff --git a/sys/alpha/linux/linux.h b/sys/alpha/linux/linux.h index f6bab97e92bb..af0eb04319f8 100644 --- a/sys/alpha/linux/linux.h +++ b/sys/alpha/linux/linux.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux.h,v 1.4 1996/01/30 22:56:29 mpp Exp $ + * $Id: linux.h,v 1.5 1996/03/02 19:37:47 peter Exp $ */ #ifndef _I386_LINUX_LINUX_H_ @@ -234,7 +234,9 @@ int linux_fixup __P((int **stack_base, struct image_params *iparams)); #define LINUX_VWERASE 14 #define LINUX_VLNEXT 15 #define LINUX_VEOL2 16 -#define LINUX_NCCS 17 +#define LINUX_NCCS 19 + +#define LINUX_POSIX_VDISABLE '\0' /* Linux c_iflag masks */ #define LINUX_IGNBRK 0x0000001 diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 968092862bd9..9aba59f556aa 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.5 1995/12/30 00:42:25 sos Exp $ + * $Id: linux_ioctl.c,v 1.6 1996/03/02 19:37:55 peter Exp $ */ #include @@ -49,6 +49,16 @@ #include #include +struct linux_termio { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + unsigned char c_line; + unsigned char c_cc[LINUX_NCC]; +}; + + struct linux_termios { unsigned long c_iflag; unsigned long c_oflag; @@ -192,7 +202,7 @@ bsd_to_linux_termios(struct termios *bsd_termios, linux_termios->c_lflag |= LINUX_IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; + linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; @@ -211,6 +221,11 @@ bsd_to_linux_termios(struct termios *bsd_termios, linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; + for (i=0; ic_cc[i] == _POSIX_VDISABLE) + linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; + } + linux_termios->c_line = 0; #ifdef DEBUG printf("LINUX: LINUX termios structure (output):\n"); @@ -225,6 +240,7 @@ bsd_to_linux_termios(struct termios *bsd_termios, #endif } + static void linux_to_bsd_termios(struct linux_termios *linux_termios, struct termios *bsd_termios) @@ -340,6 +356,11 @@ linux_to_bsd_termios(struct linux_termios *linux_termios, bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; + for (i=0; ic_cc[i] == LINUX_POSIX_VDISABLE) + bsd_termios->c_cc[i] = _POSIX_VDISABLE; + } + bsd_termios->c_ispeed = bsd_termios->c_ospeed = linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); #ifdef DEBUG @@ -355,12 +376,49 @@ linux_to_bsd_termios(struct linux_termios *linux_termios, #endif } + +static void +bsd_to_linux_termio(struct termios *bsd_termios, + struct linux_termio *linux_termio) +{ + struct linux_termios tmios; + + bsd_to_linux_termios(bsd_termios, &tmios); + linux_termio->c_iflag = tmios.c_iflag; + linux_termio->c_oflag = tmios.c_oflag; + linux_termio->c_cflag = tmios.c_cflag; + linux_termio->c_lflag = tmios.c_lflag; + linux_termio->c_line = tmios.c_line; + memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC); +} + +static void +linux_to_bsd_termio(struct linux_termio *linux_termio, + struct termios *bsd_termios) +{ + struct linux_termios tmios; + int i; + + tmios.c_iflag = linux_termio->c_iflag; + tmios.c_oflag = linux_termio->c_oflag; + tmios.c_cflag = linux_termio->c_cflag; + tmios.c_lflag = linux_termio->c_lflag; + + for (i=0; ic_cc, LINUX_NCC); + + linux_to_bsd_termios(&tmios, bsd_termios); +} + + int linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) { struct termios bsd_termios; struct winsize bsd_winsize; struct linux_termios linux_termios; + struct linux_termio linux_termio; struct linux_winsize linux_winsize; struct filedesc *fdp = p->p_fd; struct file *fp; @@ -382,6 +440,18 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) func = fp->f_ops->fo_ioctl; switch (args->cmd & 0xffff) { + + case LINUX_TCGETA: + if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) + return error; + bsd_to_linux_termio(&bsd_termios, &linux_termio); + return copyout((caddr_t)&linux_termio, (caddr_t)args->arg, + sizeof(linux_termio)); + + case LINUX_TCSETA: + linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); + return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); + case LINUX_TCGETS: if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) return error; diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index f6bab97e92bb..af0eb04319f8 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux.h,v 1.4 1996/01/30 22:56:29 mpp Exp $ + * $Id: linux.h,v 1.5 1996/03/02 19:37:47 peter Exp $ */ #ifndef _I386_LINUX_LINUX_H_ @@ -234,7 +234,9 @@ int linux_fixup __P((int **stack_base, struct image_params *iparams)); #define LINUX_VWERASE 14 #define LINUX_VLNEXT 15 #define LINUX_VEOL2 16 -#define LINUX_NCCS 17 +#define LINUX_NCCS 19 + +#define LINUX_POSIX_VDISABLE '\0' /* Linux c_iflag masks */ #define LINUX_IGNBRK 0x0000001 diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c index 968092862bd9..9aba59f556aa 100644 --- a/sys/i386/linux/linux_ioctl.c +++ b/sys/i386/linux/linux_ioctl.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.5 1995/12/30 00:42:25 sos Exp $ + * $Id: linux_ioctl.c,v 1.6 1996/03/02 19:37:55 peter Exp $ */ #include @@ -49,6 +49,16 @@ #include #include +struct linux_termio { + unsigned short c_iflag; + unsigned short c_oflag; + unsigned short c_cflag; + unsigned short c_lflag; + unsigned char c_line; + unsigned char c_cc[LINUX_NCC]; +}; + + struct linux_termios { unsigned long c_iflag; unsigned long c_oflag; @@ -192,7 +202,7 @@ bsd_to_linux_termios(struct termios *bsd_termios, linux_termios->c_lflag |= LINUX_IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; + linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; @@ -211,6 +221,11 @@ bsd_to_linux_termios(struct termios *bsd_termios, linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; + for (i=0; ic_cc[i] == _POSIX_VDISABLE) + linux_termios->c_cc[i] = LINUX_POSIX_VDISABLE; + } + linux_termios->c_line = 0; #ifdef DEBUG printf("LINUX: LINUX termios structure (output):\n"); @@ -225,6 +240,7 @@ bsd_to_linux_termios(struct termios *bsd_termios, #endif } + static void linux_to_bsd_termios(struct linux_termios *linux_termios, struct termios *bsd_termios) @@ -340,6 +356,11 @@ linux_to_bsd_termios(struct linux_termios *linux_termios, bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; + for (i=0; ic_cc[i] == LINUX_POSIX_VDISABLE) + bsd_termios->c_cc[i] = _POSIX_VDISABLE; + } + bsd_termios->c_ispeed = bsd_termios->c_ospeed = linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); #ifdef DEBUG @@ -355,12 +376,49 @@ linux_to_bsd_termios(struct linux_termios *linux_termios, #endif } + +static void +bsd_to_linux_termio(struct termios *bsd_termios, + struct linux_termio *linux_termio) +{ + struct linux_termios tmios; + + bsd_to_linux_termios(bsd_termios, &tmios); + linux_termio->c_iflag = tmios.c_iflag; + linux_termio->c_oflag = tmios.c_oflag; + linux_termio->c_cflag = tmios.c_cflag; + linux_termio->c_lflag = tmios.c_lflag; + linux_termio->c_line = tmios.c_line; + memcpy(linux_termio->c_cc, tmios.c_cc, LINUX_NCC); +} + +static void +linux_to_bsd_termio(struct linux_termio *linux_termio, + struct termios *bsd_termios) +{ + struct linux_termios tmios; + int i; + + tmios.c_iflag = linux_termio->c_iflag; + tmios.c_oflag = linux_termio->c_oflag; + tmios.c_cflag = linux_termio->c_cflag; + tmios.c_lflag = linux_termio->c_lflag; + + for (i=0; ic_cc, LINUX_NCC); + + linux_to_bsd_termios(&tmios, bsd_termios); +} + + int linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) { struct termios bsd_termios; struct winsize bsd_winsize; struct linux_termios linux_termios; + struct linux_termio linux_termio; struct linux_winsize linux_winsize; struct filedesc *fdp = p->p_fd; struct file *fp; @@ -382,6 +440,18 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) func = fp->f_ops->fo_ioctl; switch (args->cmd & 0xffff) { + + case LINUX_TCGETA: + if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) + return error; + bsd_to_linux_termio(&bsd_termios, &linux_termio); + return copyout((caddr_t)&linux_termio, (caddr_t)args->arg, + sizeof(linux_termio)); + + case LINUX_TCSETA: + linux_to_bsd_termio((struct linux_termio *)args->arg, &bsd_termios); + return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); + case LINUX_TCGETS: if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) return error;