1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/termios_internal.h>
5 * c_cc characters in the termio structure. Oh, how I love being
6 * backwardly compatible. Notice that character 4 and 5 are
7 * interpreted differently depending on whether ICANON is set in
8 * c_lflag. If it's set, they are used as _VEOF and _VEOL, otherwise
9 * as _VMIN and V_TIME. This is for compatibility with OSF/1 (which
10 * is compatible with sysV)...
15 int kernel_termios_to_user_termio(struct termio __user
*termio
,
16 struct ktermios
*termios
)
19 memset(&v
, 0, sizeof(struct termio
));
20 v
.c_iflag
= termios
->c_iflag
;
21 v
.c_oflag
= termios
->c_oflag
;
22 v
.c_cflag
= termios
->c_cflag
;
23 v
.c_lflag
= termios
->c_lflag
;
24 v
.c_line
= termios
->c_line
;
25 memcpy(v
.c_cc
, termios
->c_cc
, NCC
);
26 if (!(v
.c_lflag
& ICANON
)) {
27 v
.c_cc
[_VMIN
] = termios
->c_cc
[VMIN
];
28 v
.c_cc
[_VTIME
] = termios
->c_cc
[VTIME
];
30 return copy_to_user(termio
, &v
, sizeof(struct termio
));
33 int user_termios_to_kernel_termios(struct ktermios
*k
,
34 struct termios2 __user
*u
)
37 err
= get_user(k
->c_iflag
, &u
->c_iflag
);
38 err
|= get_user(k
->c_oflag
, &u
->c_oflag
);
39 err
|= get_user(k
->c_cflag
, &u
->c_cflag
);
40 err
|= get_user(k
->c_lflag
, &u
->c_lflag
);
41 err
|= get_user(k
->c_line
, &u
->c_line
);
42 err
|= copy_from_user(k
->c_cc
, u
->c_cc
, NCCS
);
43 if (k
->c_lflag
& ICANON
) {
44 err
|= get_user(k
->c_cc
[VEOF
], &u
->c_cc
[VEOF
]);
45 err
|= get_user(k
->c_cc
[VEOL
], &u
->c_cc
[VEOL
]);
47 err
|= get_user(k
->c_cc
[VMIN
], &u
->c_cc
[_VMIN
]);
48 err
|= get_user(k
->c_cc
[VTIME
], &u
->c_cc
[_VTIME
]);
50 err
|= get_user(k
->c_ispeed
, &u
->c_ispeed
);
51 err
|= get_user(k
->c_ospeed
, &u
->c_ospeed
);
55 int kernel_termios_to_user_termios(struct termios2 __user
*u
,
59 err
= put_user(k
->c_iflag
, &u
->c_iflag
);
60 err
|= put_user(k
->c_oflag
, &u
->c_oflag
);
61 err
|= put_user(k
->c_cflag
, &u
->c_cflag
);
62 err
|= put_user(k
->c_lflag
, &u
->c_lflag
);
63 err
|= put_user(k
->c_line
, &u
->c_line
);
64 err
|= copy_to_user(u
->c_cc
, k
->c_cc
, NCCS
);
65 if (!(k
->c_lflag
& ICANON
)) {
66 err
|= put_user(k
->c_cc
[VMIN
], &u
->c_cc
[_VMIN
]);
67 err
|= put_user(k
->c_cc
[VTIME
], &u
->c_cc
[_VTIME
]);
69 err
|= put_user(k
->c_cc
[VEOF
], &u
->c_cc
[VEOF
]);
70 err
|= put_user(k
->c_cc
[VEOL
], &u
->c_cc
[VEOL
]);
72 err
|= put_user(k
->c_ispeed
, &u
->c_ispeed
);
73 err
|= put_user(k
->c_ospeed
, &u
->c_ospeed
);
77 int user_termios_to_kernel_termios_1(struct ktermios
*k
,
78 struct termios __user
*u
)
81 err
= get_user(k
->c_iflag
, &u
->c_iflag
);
82 err
|= get_user(k
->c_oflag
, &u
->c_oflag
);
83 err
|= get_user(k
->c_cflag
, &u
->c_cflag
);
84 err
|= get_user(k
->c_lflag
, &u
->c_lflag
);
85 err
|= get_user(k
->c_line
, &u
->c_line
);
86 err
|= copy_from_user(k
->c_cc
, u
->c_cc
, NCCS
);
87 if (k
->c_lflag
& ICANON
) {
88 err
|= get_user(k
->c_cc
[VEOF
], &u
->c_cc
[VEOF
]);
89 err
|= get_user(k
->c_cc
[VEOL
], &u
->c_cc
[VEOL
]);
91 err
|= get_user(k
->c_cc
[VMIN
], &u
->c_cc
[_VMIN
]);
92 err
|= get_user(k
->c_cc
[VTIME
], &u
->c_cc
[_VTIME
]);
97 int kernel_termios_to_user_termios_1(struct termios __user
*u
,
101 err
= put_user(k
->c_iflag
, &u
->c_iflag
);
102 err
|= put_user(k
->c_oflag
, &u
->c_oflag
);
103 err
|= put_user(k
->c_cflag
, &u
->c_cflag
);
104 err
|= put_user(k
->c_lflag
, &u
->c_lflag
);
105 err
|= put_user(k
->c_line
, &u
->c_line
);
106 err
|= copy_to_user(u
->c_cc
, k
->c_cc
, NCCS
);
107 if (!(k
->c_lflag
& ICANON
)) {
108 err
|= put_user(k
->c_cc
[VMIN
], &u
->c_cc
[_VMIN
]);
109 err
|= put_user(k
->c_cc
[VTIME
], &u
->c_cc
[_VTIME
]);
111 err
|= put_user(k
->c_cc
[VEOF
], &u
->c_cc
[VEOF
]);
112 err
|= put_user(k
->c_cc
[VEOL
], &u
->c_cc
[VEOL
]);