diff options
author | peter <peter@FreeBSD.org> | 1996-03-03 19:07:50 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-03-03 19:07:50 +0000 |
commit | f14a4d4e3f7dd9c0fbb609480912908d4ba2e868 (patch) | |
tree | 5a86785e85477543a727c006b9c4fd321fb64d7e /sys/compat | |
parent | 32c0e11a4b2d5700d745f8186f6de609d59fa137 (diff) | |
download | FreeBSD-src-f14a4d4e3f7dd9c0fbb609480912908d4ba2e868.zip FreeBSD-src-f14a4d4e3f7dd9c0fbb609480912908d4ba2e868.tar.gz |
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 <rsanders@mindspring.com>
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 9680928..9aba59f 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 <sys/param.h> @@ -49,6 +49,16 @@ #include <i386/linux/linux.h> #include <i386/linux/linux_proto.h> +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; i<LINUX_NCCS; i++) - linux_termios->c_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; i<LINUX_NCCS; i++) { + if (linux_termios->c_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; i<NCCS; i++) { + if (bsd_termios->c_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; i<LINUX_NCCS; i++) + tmios.c_cc[i] = LINUX_POSIX_VDISABLE; + memcpy(tmios.c_cc, linux_termio->c_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; |