123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- // SPDX-License-Identifier: GPL-2.0
- #include <linux/termios_internal.h>
- /*
- * c_cc characters in the termio structure. Oh, how I love being
- * backwardly compatible. Notice that character 4 and 5 are
- * interpreted differently depending on whether ICANON is set in
- * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise
- * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which
- * is compatible with sysV)...
- */
- #define _VMIN 4
- #define _VTIME 5
- 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);
- if (!(v.c_lflag & ICANON)) {
- v.c_cc[_VMIN] = termios->c_cc[VMIN];
- v.c_cc[_VTIME] = termios->c_cc[VTIME];
- }
- return copy_to_user(termio, &v, sizeof(struct termio));
- }
- int user_termios_to_kernel_termios(struct ktermios *k,
- struct termios2 __user *u)
- {
- int err;
- err = get_user(k->c_iflag, &u->c_iflag);
- err |= get_user(k->c_oflag, &u->c_oflag);
- err |= get_user(k->c_cflag, &u->c_cflag);
- err |= get_user(k->c_lflag, &u->c_lflag);
- err |= get_user(k->c_line, &u->c_line);
- err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
- if (k->c_lflag & ICANON) {
- err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
- err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
- } else {
- err |= get_user(k->c_cc[VMIN], &u->c_cc[_VMIN]);
- err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
- }
- err |= get_user(k->c_ispeed, &u->c_ispeed);
- err |= get_user(k->c_ospeed, &u->c_ospeed);
- return err;
- }
- int kernel_termios_to_user_termios(struct termios2 __user *u,
- struct ktermios *k)
- {
- int err;
- err = put_user(k->c_iflag, &u->c_iflag);
- err |= put_user(k->c_oflag, &u->c_oflag);
- err |= put_user(k->c_cflag, &u->c_cflag);
- err |= put_user(k->c_lflag, &u->c_lflag);
- err |= put_user(k->c_line, &u->c_line);
- err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
- if (!(k->c_lflag & ICANON)) {
- err |= put_user(k->c_cc[VMIN], &u->c_cc[_VMIN]);
- err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
- } else {
- err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
- err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
- }
- err |= put_user(k->c_ispeed, &u->c_ispeed);
- err |= put_user(k->c_ospeed, &u->c_ospeed);
- return err;
- }
- int user_termios_to_kernel_termios_1(struct ktermios *k,
- struct termios __user *u)
- {
- int err;
- err = get_user(k->c_iflag, &u->c_iflag);
- err |= get_user(k->c_oflag, &u->c_oflag);
- err |= get_user(k->c_cflag, &u->c_cflag);
- err |= get_user(k->c_lflag, &u->c_lflag);
- err |= get_user(k->c_line, &u->c_line);
- err |= copy_from_user(k->c_cc, u->c_cc, NCCS);
- if (k->c_lflag & ICANON) {
- err |= get_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
- err |= get_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
- } else {
- err |= get_user(k->c_cc[VMIN], &u->c_cc[_VMIN]);
- err |= get_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
- }
- return err;
- }
- int kernel_termios_to_user_termios_1(struct termios __user *u,
- struct ktermios *k)
- {
- int err;
- err = put_user(k->c_iflag, &u->c_iflag);
- err |= put_user(k->c_oflag, &u->c_oflag);
- err |= put_user(k->c_cflag, &u->c_cflag);
- err |= put_user(k->c_lflag, &u->c_lflag);
- err |= put_user(k->c_line, &u->c_line);
- err |= copy_to_user(u->c_cc, k->c_cc, NCCS);
- if (!(k->c_lflag & ICANON)) {
- err |= put_user(k->c_cc[VMIN], &u->c_cc[_VMIN]);
- err |= put_user(k->c_cc[VTIME], &u->c_cc[_VTIME]);
- } else {
- err |= put_user(k->c_cc[VEOF], &u->c_cc[VEOF]);
- err |= put_user(k->c_cc[VEOL], &u->c_cc[VEOL]);
- }
- return err;
- }
|