summaryrefslogtreecommitdiff
path: root/drivers/tty/tty_ioctl.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2022-08-21 02:36:09 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-09-09 11:44:34 +0300
commit1d5d66825610bb7be23e2229731261c8e99eaa28 (patch)
treea8390bbd15c5fd08ec5f2bf8e222f132d4d56346 /drivers/tty/tty_ioctl.c
parent408e532e80997be64caf8cdf45f2ff53c2279725 (diff)
downloadlinux-1d5d66825610bb7be23e2229731261c8e99eaa28.tar.xz
termios: uninline conversion helpers
default go into drivers/tty/tty_ioctl.c, unusual - into arch/*/kernel/termios.c (only alpha and sparc have those). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Link: https://lore.kernel.org/r/YxDmeUBHo0s/Ew8b@ZenIV Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_ioctl.c')
-rw-r--r--drivers/tty/tty_ioctl.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index 31d11230e778..026429276637 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -374,6 +374,80 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
}
EXPORT_SYMBOL_GPL(tty_set_termios);
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+__weak int user_termio_to_kernel_termios(struct ktermios *termios,
+ struct termio __user *termio)
+{
+ struct termio v;
+
+ if (copy_from_user(&v, termio, sizeof(struct termio)))
+ return -EFAULT;
+
+ termios->c_iflag = (0xffff0000 & termios->c_iflag) | v.c_iflag;
+ termios->c_oflag = (0xffff0000 & termios->c_oflag) | v.c_oflag;
+ termios->c_cflag = (0xffff0000 & termios->c_cflag) | v.c_cflag;
+ termios->c_lflag = (0xffff0000 & termios->c_lflag) | v.c_lflag;
+ termios->c_line = (0xffff0000 & termios->c_lflag) | v.c_line;
+ memcpy(termios->c_cc, v.c_cc, NCC);
+ return 0;
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+__weak int kernel_termios_to_user_termio(struct termio __user *termio,
+ struct ktermios *termios)
+{
+ struct termio v;
+ memset(&v, 0, sizeof(struct termio));
+ v.c_iflag = termios->c_iflag;
+ v.c_oflag = termios->c_oflag;
+ v.c_cflag = termios->c_cflag;
+ v.c_lflag = termios->c_lflag;
+ v.c_line = termios->c_line;
+ memcpy(v.c_cc, termios->c_cc, NCC);
+ return copy_to_user(termio, &v, sizeof(struct termio));
+}
+
+#ifdef TCGETS2
+__weak int user_termios_to_kernel_termios(struct ktermios *k,
+ struct termios2 __user *u)
+{
+ return copy_from_user(k, u, sizeof(struct termios2));
+}
+__weak int kernel_termios_to_user_termios(struct termios2 __user *u,
+ struct ktermios *k)
+{
+ return copy_to_user(u, k, sizeof(struct termios2));
+}
+__weak int user_termios_to_kernel_termios_1(struct ktermios *k,
+ struct termios __user *u)
+{
+ return copy_from_user(k, u, sizeof(struct termios));
+}
+__weak int kernel_termios_to_user_termios_1(struct termios __user *u,
+ struct ktermios *k)
+{
+ return copy_to_user(u, k, sizeof(struct termios));
+}
+
+#else
+
+__weak int user_termios_to_kernel_termios(struct ktermios *k,
+ struct termios __user *u)
+{
+ return copy_from_user(k, u, sizeof(struct termios));
+}
+__weak int kernel_termios_to_user_termios(struct termios __user *u,
+ struct ktermios *k)
+{
+ return copy_to_user(u, k, sizeof(struct termios));
+}
+#endif /* TCGETS2 */
+
/**
* set_termios - set termios values for a tty
* @tty: terminal device