Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c00a4ca7d8 | ||
|
882957c7dd |
@ -283,6 +283,12 @@ AC_CHECK_TYPES([struct stat64, struct __old_kernel_stat],,,
|
||||
[#include <sys/types.h>
|
||||
#include <asm/stat.h>])
|
||||
|
||||
AC_CHECK_TYPES([struct termios2],,,
|
||||
[#include <linux/termios.h>])
|
||||
|
||||
AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed],,,
|
||||
[#include <linux/termios.h>])
|
||||
|
||||
AC_CHECK_TYPES([struct user_desc],
|
||||
[AC_CHECK_MEMBERS([struct user_desc.lm],,,
|
||||
[#include <asm/ldt.h>])],,
|
||||
|
279
term.c
279
term.c
@ -18,6 +18,151 @@
|
||||
#include "xlat/baud_options.h"
|
||||
#include "xlat/modem_flags.h"
|
||||
|
||||
#include "xlat/term_cflags.h"
|
||||
#include "xlat/term_cflags_csize.h"
|
||||
#include "xlat/term_iflags.h"
|
||||
#include "xlat/term_lflags.h"
|
||||
#include "xlat/term_oflags.h"
|
||||
#include "xlat/term_oflags_bsdly.h"
|
||||
#include "xlat/term_oflags_crdly.h"
|
||||
#include "xlat/term_oflags_ffdly.h"
|
||||
#include "xlat/term_oflags_nldly.h"
|
||||
#include "xlat/term_oflags_tabdly.h"
|
||||
#include "xlat/term_oflags_vtdly.h"
|
||||
|
||||
#include "xlat/term_line_discs.h"
|
||||
|
||||
#include "xlat/termio_cc.h"
|
||||
#include "xlat/termios_cc.h"
|
||||
|
||||
static void
|
||||
decode_oflag(uint64_t val)
|
||||
{
|
||||
static const struct {
|
||||
const struct xlat *xl;
|
||||
uint64_t mask;
|
||||
const char *dfl;
|
||||
} xlats[] = {
|
||||
{ term_oflags_nldly, NLDLY, "NL?" },
|
||||
{ term_oflags_crdly, CRDLY, "CR?" },
|
||||
{ term_oflags_tabdly, TABDLY, "TAB?" },
|
||||
{ term_oflags_bsdly, BSDLY, "BS?" },
|
||||
{ term_oflags_vtdly, VTDLY, "VT?" },
|
||||
{ term_oflags_ffdly, FFDLY, "FF?" },
|
||||
};
|
||||
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(xlats); i++) {
|
||||
printxval64(xlats[i].xl, val & xlats[i].mask, xlats[i].dfl);
|
||||
tprints("|");
|
||||
|
||||
val &= ~xlats[i].mask;
|
||||
}
|
||||
|
||||
printflags64(term_oflags, val, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_cflag(uint64_t val)
|
||||
{
|
||||
printxval64(baud_options, val & CBAUD, "B???");
|
||||
tprints("|");
|
||||
if (val & CIBAUD) {
|
||||
printxval64(baud_options, (val & CIBAUD) >> IBSHIFT, "B???");
|
||||
tprintf("<<IBSHIFT|");
|
||||
}
|
||||
printxval64(term_cflags_csize, val & CSIZE, "CS?");
|
||||
tprints("|");
|
||||
|
||||
val &= ~(CBAUD | CIBAUD | CSIZE);
|
||||
printflags64(term_cflags, val, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_flags(uint64_t iflag, uint64_t oflag, uint64_t cflag, uint64_t lflag)
|
||||
{
|
||||
tprints("c_iflag=");
|
||||
printflags64(term_iflags, iflag, NULL);
|
||||
tprints(", c_oflag=");
|
||||
decode_oflag(oflag);
|
||||
tprints(", c_cflag=");
|
||||
decode_cflag(cflag);
|
||||
tprints(", c_lflag=");
|
||||
printflags64(term_lflags, lflag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_line_disc(uint64_t line)
|
||||
{
|
||||
tprints("c_line=");
|
||||
printxval(term_line_discs, line, "N_???");
|
||||
}
|
||||
|
||||
static void
|
||||
print_cc_char(bool *first, const unsigned char *data, const char *s,
|
||||
unsigned idx)
|
||||
{
|
||||
if (*first)
|
||||
*first = false;
|
||||
else
|
||||
tprints(", ");
|
||||
|
||||
if (s)
|
||||
tprintf("[%s] = ", s);
|
||||
else
|
||||
tprintf("[%u] = ", idx);
|
||||
|
||||
tprintf("%#hhx", data[idx]);
|
||||
}
|
||||
|
||||
static void
|
||||
decode_term_cc(const struct xlat *xl, const unsigned char *data, unsigned size)
|
||||
{
|
||||
unsigned i = 0;
|
||||
bool first = true;
|
||||
|
||||
tprints("[");
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
print_cc_char(&first, data, xlookup(xl, i), i);
|
||||
|
||||
tprints("]");
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
static void
|
||||
decode_termios2(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
struct termios2 tios;
|
||||
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tios))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tios.c_iflag, tios.c_oflag, tios.c_cflag, tios.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tios.c_line);
|
||||
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%u, c_cc[VTIME]=%u",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints(", c_cc=");
|
||||
/* SPARC has two additional bytes in c_cc. */
|
||||
decode_term_cc(termios_cc, tios.c_cc, sizeof(tios.c_cc));
|
||||
|
||||
tprintf(", c_ispeed=%u", tios.c_ispeed);
|
||||
tprintf(", c_ospeed=%u", tios.c_ospeed);
|
||||
}
|
||||
tprints("}");
|
||||
}
|
||||
#endif /* HAVE_STRUCT_TERMIOS2 */
|
||||
|
||||
static void
|
||||
decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
@ -26,26 +171,38 @@ decode_termios(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tios))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tios.c_iflag, tios.c_oflag, tios.c_cflag, tios.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("{");
|
||||
printxval(baud_options, tios.c_cflag & CBAUD, "B???");
|
||||
tprintf(" %sopost %sisig %sicanon %secho ...}",
|
||||
(tios.c_oflag & OPOST) ? "" : "-",
|
||||
(tios.c_lflag & ISIG) ? "" : "-",
|
||||
(tios.c_lflag & ICANON) ? "" : "-",
|
||||
(tios.c_lflag & ECHO) ? "" : "-");
|
||||
return;
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tios.c_line);
|
||||
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%u, c_cc[VTIME]=%u",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints(", c_cc=");
|
||||
/*
|
||||
* Fun fact: MIPS has NCCS defined to 23, SPARC to 17 and
|
||||
* everything else to 19.
|
||||
*/
|
||||
decode_term_cc(termios_cc, tios.c_cc,
|
||||
MIN(NCCS, sizeof(tios.c_cc)));
|
||||
|
||||
/*
|
||||
* alpha and powerpc have those in struct termios instead of
|
||||
* having a separate struct termios2.
|
||||
*/
|
||||
#ifdef HAVE_STRUCT_TERMIOS_C_ISPEED
|
||||
tprintf(", c_ispeed=%u", tios.c_ispeed);
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_TERMIOS_C_OSPEED
|
||||
tprintf(", c_ospeed=%u", tios.c_ospeed);
|
||||
#endif
|
||||
}
|
||||
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
|
||||
(long) tios.c_iflag, (long) tios.c_oflag);
|
||||
tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
|
||||
(long) tios.c_cflag, (long) tios.c_lflag);
|
||||
tprintf("c_line=%u, ", tios.c_line);
|
||||
if (!(tios.c_lflag & ICANON))
|
||||
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
|
||||
tios.c_cc[VMIN], tios.c_cc[VTIME]);
|
||||
tprints("c_cc=");
|
||||
print_quoted_string((char *) tios.c_cc, NCCS, QUOTE_FORCE_HEX);
|
||||
tprints("}");
|
||||
}
|
||||
|
||||
@ -53,39 +210,40 @@ static void
|
||||
decode_termio(struct tcb *const tcp, const kernel_ulong_t addr)
|
||||
{
|
||||
struct termio tio;
|
||||
int i;
|
||||
|
||||
tprints(", ");
|
||||
if (umove_or_printaddr(tcp, addr, &tio))
|
||||
return;
|
||||
|
||||
tprints("{");
|
||||
decode_flags(tio.c_iflag, tio.c_oflag, tio.c_cflag, tio.c_lflag);
|
||||
tprints(", ");
|
||||
|
||||
if (abbrev(tcp)) {
|
||||
tprints("{");
|
||||
printxval(baud_options, tio.c_cflag & CBAUD, "B???");
|
||||
tprintf(" %sopost %sisig %sicanon %secho ...}",
|
||||
(tio.c_oflag & OPOST) ? "" : "-",
|
||||
(tio.c_lflag & ISIG) ? "" : "-",
|
||||
(tio.c_lflag & ICANON) ? "" : "-",
|
||||
(tio.c_lflag & ECHO) ? "" : "-");
|
||||
return;
|
||||
}
|
||||
tprintf("{c_iflags=%#lx, c_oflags=%#lx, ",
|
||||
(long) tio.c_iflag, (long) tio.c_oflag);
|
||||
tprintf("c_cflags=%#lx, c_lflags=%#lx, ",
|
||||
(long) tio.c_cflag, (long) tio.c_lflag);
|
||||
tprintf("c_line=%u, ", tio.c_line);
|
||||
#ifdef _VMIN
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf("c_cc[_VMIN]=%d, c_cc[_VTIME]=%d, ",
|
||||
tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
|
||||
tprints("...");
|
||||
} else {
|
||||
decode_line_disc(tio.c_line);
|
||||
|
||||
#ifdef _VMIN /* thanks, alpha and powerpc */
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf(", c_cc[_VMIN]=%d, c_cc[_VTIME]=%d",
|
||||
tio.c_cc[_VMIN], tio.c_cc[_VTIME]);
|
||||
|
||||
tprints(", c_cc=");
|
||||
decode_term_cc(termio_cc, tio.c_cc,
|
||||
MIN(NCC, sizeof(tio.c_cc)));
|
||||
#else /* !_VMIN */
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf("c_cc[VMIN]=%d, c_cc[VTIME]=%d, ",
|
||||
tio.c_cc[VMIN], tio.c_cc[VTIME]);
|
||||
if (!(tio.c_lflag & ICANON))
|
||||
tprintf(", c_cc[VMIN]=%d, c_cc[VTIME]=%d",
|
||||
tio.c_cc[VMIN], tio.c_cc[VTIME]);
|
||||
|
||||
tprints(", c_cc=");
|
||||
decode_term_cc(termios_cc, tio.c_cc,
|
||||
MIN(NCC, sizeof(tio.c_cc)));
|
||||
#endif /* !_VMIN */
|
||||
tprints("c_cc=\"");
|
||||
for (i = 0; i < NCC; i++)
|
||||
tprintf("\\x%02x", tio.c_cc[i]);
|
||||
tprints("\"}");
|
||||
}
|
||||
|
||||
tprints("}");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -132,27 +290,36 @@ term_ioctl(struct tcb *const tcp, const unsigned int code,
|
||||
const kernel_ulong_t arg)
|
||||
{
|
||||
switch (code) {
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
/* struct termios2 */
|
||||
# ifdef TCGETS2
|
||||
case TCGETS2:
|
||||
# endif
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
ATTRIBUTE_FALLTHROUGH;
|
||||
# ifdef TCSETS2
|
||||
case TCSETS2:
|
||||
# endif
|
||||
# ifdef TCSETSW2
|
||||
case TCSETSW2:
|
||||
# endif
|
||||
# ifdef TCSETSF2
|
||||
case TCSETSF2:
|
||||
# endif
|
||||
decode_termios2(tcp, arg);
|
||||
break;
|
||||
#endif /* HAVE_STRUCT_TERMIOS2 */
|
||||
|
||||
/* struct termios */
|
||||
case TCGETS:
|
||||
#ifdef TCGETS2
|
||||
case TCGETS2:
|
||||
#endif
|
||||
case TIOCGLCKTRMIOS:
|
||||
if (entering(tcp))
|
||||
return 0;
|
||||
ATTRIBUTE_FALLTHROUGH;
|
||||
case TCSETS:
|
||||
#ifdef TCSETS2
|
||||
case TCSETS2:
|
||||
#endif
|
||||
case TCSETSW:
|
||||
#ifdef TCSETSW2
|
||||
case TCSETSW2:
|
||||
#endif
|
||||
case TCSETSF:
|
||||
#ifdef TCSETSF2
|
||||
case TCSETSF2:
|
||||
#endif
|
||||
case TIOCSLCKTRMIOS:
|
||||
decode_termios(tcp, arg);
|
||||
break;
|
||||
|
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
@ -171,6 +171,8 @@ ioctl_scsi
|
||||
ioctl_sg_io_v3
|
||||
ioctl_sg_io_v4
|
||||
ioctl_sock_gifconf
|
||||
ioctl_termios
|
||||
ioctl_termios-v
|
||||
ioctl_uffdio
|
||||
ioctl_v4l2
|
||||
ioperm
|
||||
|
@ -142,6 +142,8 @@ ioctl_scsi +ioctl.test
|
||||
ioctl_sg_io_v3 +ioctl.test
|
||||
ioctl_sg_io_v4 +ioctl.test
|
||||
ioctl_sock_gifconf +ioctl.test -a28 -s1
|
||||
ioctl_termios +ioctl.test
|
||||
ioctl_termios-v +ioctl.test -v
|
||||
ioctl_uffdio +ioctl.test
|
||||
ioctl_v4l2 +ioctl.test
|
||||
ioperm -a27
|
||||
|
2
tests/ioctl_termios-v.c
Normal file
2
tests/ioctl_termios-v.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define VERBOSE 1
|
||||
#include "ioctl_termios.c"
|
908
tests/ioctl_termios.c
Normal file
908
tests/ioctl_termios.c
Normal file
@ -0,0 +1,908 @@
|
||||
/*
|
||||
* Check decoding of struct termio{,s,s2}-related commands of ioctl syscall.
|
||||
*
|
||||
* Copyright (c) 2018 The strace developers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/termios.h>
|
||||
#include <linux/tty.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "xlat.h"
|
||||
#include "xlat/baud_options.h"
|
||||
#include "xlat/term_line_discs.h"
|
||||
|
||||
#ifndef VERBOSE
|
||||
# define VERBOSE 0
|
||||
#endif
|
||||
|
||||
#define PRINT_FLAG(val_, f_) \
|
||||
do { \
|
||||
if ((val_ & f_)) { \
|
||||
printf("%s%s", sep, #f_); \
|
||||
val_ &= ~f_; \
|
||||
sep = "|"; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern int ioctl (int __fd, unsigned long int __request, ...);
|
||||
|
||||
static void
|
||||
print_flags(tcflag_t iflag, tcflag_t oflag, tcflag_t cflag, tcflag_t lflag)
|
||||
{
|
||||
const char *sep = "";
|
||||
|
||||
printf("c_iflag=");
|
||||
PRINT_FLAG(iflag, IGNBRK);
|
||||
PRINT_FLAG(iflag, BRKINT);
|
||||
PRINT_FLAG(iflag, IGNPAR);
|
||||
PRINT_FLAG(iflag, PARMRK);
|
||||
PRINT_FLAG(iflag, INPCK);
|
||||
PRINT_FLAG(iflag, ISTRIP);
|
||||
PRINT_FLAG(iflag, INLCR);
|
||||
PRINT_FLAG(iflag, IGNCR);
|
||||
PRINT_FLAG(iflag, ICRNL);
|
||||
PRINT_FLAG(iflag, IUCLC);
|
||||
PRINT_FLAG(iflag, IXON);
|
||||
PRINT_FLAG(iflag, IXANY);
|
||||
PRINT_FLAG(iflag, IXOFF);
|
||||
PRINT_FLAG(iflag, IMAXBEL);
|
||||
PRINT_FLAG(iflag, IUTF8);
|
||||
if (iflag)
|
||||
printf("%s%#x", sep, iflag);
|
||||
|
||||
/* oflag */
|
||||
static struct {
|
||||
tcflag_t val;
|
||||
const char *prefix;
|
||||
unsigned int max_val;
|
||||
} vals[] = {
|
||||
{ NLDLY, "NL", 1 },
|
||||
{ CRDLY, "CR", 3 },
|
||||
{ TABDLY, "TAB", 3 },
|
||||
{ BSDLY, "BS", 1 },
|
||||
{ VTDLY, "VT", 1 },
|
||||
{ FFDLY, "FF", 1 },
|
||||
};
|
||||
|
||||
printf(", c_oflag=");
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_SIZE(vals); i++) {
|
||||
int val = (oflag & vals[i].val) /
|
||||
(vals[i].val / vals[i].max_val);
|
||||
#ifndef __alpha__
|
||||
if (i == 2 && val == 3) /* XTABS */
|
||||
printf("XTABS|");
|
||||
else
|
||||
#endif
|
||||
printf("%s%u|", vals[i].prefix, val);
|
||||
oflag &= ~vals[i].val;
|
||||
}
|
||||
|
||||
sep = "";
|
||||
#if defined __alpha__ && defined XTABS
|
||||
PRINT_FLAG(oflag, XTABS);
|
||||
#endif
|
||||
PRINT_FLAG(oflag, OPOST);
|
||||
PRINT_FLAG(oflag, OLCUC);
|
||||
PRINT_FLAG(oflag, ONLCR);
|
||||
PRINT_FLAG(oflag, OCRNL);
|
||||
PRINT_FLAG(oflag, ONOCR);
|
||||
PRINT_FLAG(oflag, ONLRET);
|
||||
PRINT_FLAG(oflag, OFILL);
|
||||
PRINT_FLAG(oflag, OFDEL);
|
||||
#ifdef PAGEOUT
|
||||
PRINT_FLAG(oflag, PAGEOUT);
|
||||
#endif
|
||||
#ifdef WRAP
|
||||
PRINT_FLAG(oflag, WRAP);
|
||||
#endif
|
||||
if (oflag)
|
||||
printf("%s%#x", sep, oflag);
|
||||
|
||||
/* cflag */
|
||||
sep = "";
|
||||
printf(", c_cflag=");
|
||||
printxval(baud_options, cflag & CBAUD, "B???");
|
||||
printf("|");
|
||||
if (cflag & CIBAUD) {
|
||||
printxval(baud_options, (cflag & CIBAUD) >> IBSHIFT, "B???");
|
||||
printf("<<IBSHIFT|");
|
||||
}
|
||||
switch (cflag & CSIZE) {
|
||||
case CS5:
|
||||
printf("CS5|");
|
||||
break;
|
||||
case CS6:
|
||||
printf("CS6|");
|
||||
break;
|
||||
case CS7:
|
||||
printf("CS7|");
|
||||
break;
|
||||
case CS8:
|
||||
printf("CS8|");
|
||||
break;
|
||||
}
|
||||
cflag &= ~(CBAUD | CIBAUD | CSIZE);
|
||||
|
||||
PRINT_FLAG(cflag, CSTOPB);
|
||||
PRINT_FLAG(cflag, CREAD);
|
||||
PRINT_FLAG(cflag, PARENB);
|
||||
PRINT_FLAG(cflag, PARODD);
|
||||
PRINT_FLAG(cflag, HUPCL);
|
||||
PRINT_FLAG(cflag, CLOCAL);
|
||||
#ifdef CTVB
|
||||
PRINT_FLAG(cflag, CTVB);
|
||||
#endif
|
||||
#ifdef CMSPAR
|
||||
PRINT_FLAG(cflag, CMSPAR);
|
||||
#endif
|
||||
#ifdef CRTSCTS
|
||||
PRINT_FLAG(cflag, CRTSCTS);
|
||||
#endif
|
||||
if (cflag)
|
||||
printf("%s%#x", sep, cflag);
|
||||
|
||||
/* lflag */
|
||||
sep = "";
|
||||
printf(", c_lflag=");
|
||||
PRINT_FLAG(lflag, ISIG);
|
||||
PRINT_FLAG(lflag, ICANON);
|
||||
PRINT_FLAG(lflag, XCASE);
|
||||
PRINT_FLAG(lflag, ECHO);
|
||||
PRINT_FLAG(lflag, ECHOE);
|
||||
PRINT_FLAG(lflag, ECHOK);
|
||||
PRINT_FLAG(lflag, ECHONL);
|
||||
PRINT_FLAG(lflag, NOFLSH);
|
||||
PRINT_FLAG(lflag, IEXTEN);
|
||||
PRINT_FLAG(lflag, ECHOCTL);
|
||||
PRINT_FLAG(lflag, ECHOPRT);
|
||||
PRINT_FLAG(lflag, ECHOKE);
|
||||
PRINT_FLAG(lflag, FLUSHO);
|
||||
PRINT_FLAG(lflag, PENDIN);
|
||||
PRINT_FLAG(lflag, TOSTOP);
|
||||
PRINT_FLAG(lflag, EXTPROC);
|
||||
#ifdef DEFECHO
|
||||
PRINT_FLAG(lflag, DEFECHO);
|
||||
#endif
|
||||
if (lflag)
|
||||
printf("%s%#x", sep, lflag);
|
||||
}
|
||||
|
||||
#define cc_def_(cc_) \
|
||||
[cc_] = #cc_
|
||||
|
||||
#if VERBOSE
|
||||
static void
|
||||
print_termios_cc(const cc_t *ccs, size_t size, bool tios)
|
||||
{
|
||||
static const char * const cc_tio_names[] = {
|
||||
#if defined __alpha__ || defined __powerpc__
|
||||
cc_def_(_VINTR),
|
||||
cc_def_(_VQUIT),
|
||||
cc_def_(_VERASE),
|
||||
cc_def_(_VKILL),
|
||||
cc_def_(_VEOF),
|
||||
cc_def_(_VMIN),
|
||||
cc_def_(_VEOL),
|
||||
cc_def_(_VTIME),
|
||||
cc_def_(_VEOL2),
|
||||
cc_def_(_VSWTC),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const char * const cc_tios_names[] = {
|
||||
cc_def_(VINTR),
|
||||
cc_def_(VQUIT),
|
||||
cc_def_(VERASE),
|
||||
cc_def_(VKILL),
|
||||
cc_def_(VEOL2),
|
||||
cc_def_(VSWTC),
|
||||
cc_def_(VSTART),
|
||||
cc_def_(VSTOP),
|
||||
cc_def_(VSUSP),
|
||||
cc_def_(VREPRINT),
|
||||
cc_def_(VDISCARD),
|
||||
cc_def_(VWERASE),
|
||||
cc_def_(VLNEXT),
|
||||
cc_def_(VEOF),
|
||||
cc_def_(VEOL),
|
||||
#ifdef VDSUSP
|
||||
cc_def_(VDSUSP),
|
||||
#endif
|
||||
#if VMIN != VEOF
|
||||
cc_def_(VMIN),
|
||||
#endif
|
||||
#if VTIME != VEOL
|
||||
cc_def_(VTIME),
|
||||
#endif
|
||||
};
|
||||
|
||||
printf("c_cc=[");
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
bool has_name = tios ?
|
||||
(i < ARRAY_SIZE(cc_tios_names)) && cc_tios_names[i] :
|
||||
#if __alpha__
|
||||
(i < ARRAY_SIZE(cc_tio_names)) && cc_tio_names[i];
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
const char *name = has_name ?
|
||||
(tios ? cc_tios_names : cc_tio_names)[i] : "";
|
||||
|
||||
printf("%s[%s%.0zu] = %#hhx",
|
||||
i ? ", " : "", name, has_name ? 0 : i, ccs[i]);
|
||||
}
|
||||
|
||||
printf("]");
|
||||
}
|
||||
#endif /* VERBOSE */
|
||||
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
static void
|
||||
print_termios2(void *tios_ptr)
|
||||
{
|
||||
struct termios2 *tios = tios_ptr;
|
||||
|
||||
printf("{");
|
||||
print_flags(tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag);
|
||||
printf(", ");
|
||||
|
||||
#if VERBOSE
|
||||
printf("c_line=");
|
||||
printxval(term_line_discs, tios->c_line, "N_???");
|
||||
printf(", ");
|
||||
|
||||
if (!(tios->c_lflag & ICANON))
|
||||
printf("c_cc[VMIN]=%hhu, c_cc[VTIME]=%u, ",
|
||||
tios->c_cc[VMIN], tios->c_cc[VTIME]);
|
||||
|
||||
print_termios_cc(tios->c_cc, sizeof(tios->c_cc), true);
|
||||
|
||||
printf(", c_ispeed=%u, c_ospeed=%u", tios->c_ispeed, tios->c_ospeed);
|
||||
#else /* !VERBOSE */
|
||||
printf("...");
|
||||
#endif /* VERBOSE */
|
||||
|
||||
printf("}");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
print_termios(void *tios_ptr)
|
||||
{
|
||||
struct termios *tios = tios_ptr;
|
||||
|
||||
printf("{");
|
||||
print_flags(tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag);
|
||||
printf(", ");
|
||||
|
||||
#if VERBOSE
|
||||
printf("c_line=");
|
||||
printxval(term_line_discs, tios->c_line, "N_???");
|
||||
printf(", ");
|
||||
|
||||
if (!(tios->c_lflag & ICANON))
|
||||
printf("c_cc[VMIN]=%hhu, c_cc[VTIME]=%u, ",
|
||||
tios->c_cc[VMIN], tios->c_cc[VTIME]);
|
||||
|
||||
print_termios_cc(tios->c_cc, sizeof(tios->c_cc), true);
|
||||
|
||||
# if HAVE_STRUCT_TERMIOS_C_ISPEED
|
||||
printf(", c_ispeed=%u", tios->c_ispeed);
|
||||
# endif
|
||||
# if HAVE_STRUCT_TERMIOS_C_OSPEED
|
||||
printf(", c_ospeed=%u", tios->c_ospeed);
|
||||
# endif
|
||||
#else /* !VERBOSE */
|
||||
printf("...");
|
||||
#endif /* VERBOSE */
|
||||
|
||||
printf("}");
|
||||
}
|
||||
|
||||
static void
|
||||
print_termio(void *tios_ptr)
|
||||
{
|
||||
struct termio *tios = tios_ptr;
|
||||
|
||||
#if VERBOSE
|
||||
# if defined __alpha__ || defined __powerpc__
|
||||
const bool alpha = true;
|
||||
const unsigned vmin = _VMIN;
|
||||
const unsigned vtime = _VTIME;
|
||||
# else
|
||||
const bool alpha = false;
|
||||
const unsigned vmin = VMIN;
|
||||
const unsigned vtime = VTIME;
|
||||
# endif
|
||||
#endif /* VERBOSE */
|
||||
|
||||
printf("{");
|
||||
print_flags(tios->c_iflag, tios->c_oflag, tios->c_cflag, tios->c_lflag);
|
||||
|
||||
printf(", ");
|
||||
|
||||
#if VERBOSE
|
||||
printf("c_line=");
|
||||
printxval(term_line_discs, tios->c_line, "N_???");
|
||||
printf(", ");
|
||||
|
||||
if (!(tios->c_lflag & ICANON))
|
||||
printf("c_cc[%sVMIN]=%hhu, c_cc[%sVTIME]=%u, ",
|
||||
alpha ? "_" : "", tios->c_cc[vmin],
|
||||
alpha ? "_" : "", tios->c_cc[vtime]);
|
||||
|
||||
print_termios_cc(tios->c_cc, sizeof(tios->c_cc), !alpha);
|
||||
#else /* !VERBOSE */
|
||||
printf("...");
|
||||
#endif /* VERBOSE */
|
||||
|
||||
printf("}");
|
||||
}
|
||||
|
||||
static void
|
||||
do_ioctl(kernel_ulong_t cmd, const char *cmd_str, int fd,
|
||||
void (*printer)(void *data), kernel_ulong_t data_ptr, bool valid,
|
||||
bool write, const char *data_str, bool can_fail)
|
||||
{
|
||||
long ret = 0;
|
||||
long saved_errno;
|
||||
void *data = (void *) (uintptr_t) data_ptr;
|
||||
|
||||
if (!write) {
|
||||
ret = ioctl(fd, cmd, data_ptr);
|
||||
saved_errno = errno;
|
||||
}
|
||||
|
||||
printf("ioctl(%d, %s, ", fd, cmd_str);
|
||||
|
||||
if (valid && !ret) {
|
||||
if (data_str)
|
||||
printf("%s", data_str);
|
||||
else
|
||||
printer(data);
|
||||
} else {
|
||||
if (data)
|
||||
printf("%#llx", (unsigned long long) data_ptr);
|
||||
else
|
||||
printf("NULL");
|
||||
}
|
||||
|
||||
if (write) {
|
||||
ret = ioctl(fd, cmd, data_ptr);
|
||||
|
||||
if (valid && ret && !can_fail)
|
||||
perror_msg_and_fail("ioctl(%d, %#llx, %#llx) = -1",
|
||||
fd, (unsigned long long) cmd,
|
||||
(unsigned long long) data_ptr);
|
||||
} else {
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
printf(") = %s\n", sprintrc(ret));
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
static const char *
|
||||
setup_termios2(void *tios_ptr, int variant)
|
||||
{
|
||||
struct termios2 *tios = tios_ptr;
|
||||
|
||||
switch (variant) {
|
||||
case 0:
|
||||
fill_memory(tios, sizeof(*tios));
|
||||
return NULL;
|
||||
|
||||
case 1:
|
||||
fill_memory_ex(tios, sizeof(*tios), 0xA5, 0x5A);
|
||||
return NULL;
|
||||
|
||||
case 2:
|
||||
memset(tios, 0, sizeof(*tios));
|
||||
|
||||
tios->c_iflag = IGNBRK|IUTF8|0xdead0000;
|
||||
tios->c_oflag = NL0|CR2|TAB3|BS0|VT1|FF0|
|
||||
#ifdef __alpha__
|
||||
XTABS|
|
||||
#endif
|
||||
OPOST|ONLCR|OFILL|
|
||||
#ifdef PAGEOUT
|
||||
PAGEOUT|
|
||||
#endif
|
||||
0xbad00000;
|
||||
tios->c_cflag = B75|(B57600<<IBSHIFT)|CS6|CSTOPB|
|
||||
#ifdef CTVB
|
||||
CTVB|
|
||||
#endif
|
||||
#ifdef CMSPAR
|
||||
CMSPAR|
|
||||
#endif
|
||||
0;
|
||||
tios->c_lflag = ISIG|ECHOE|FLUSHO|
|
||||
#ifdef DEFECHO
|
||||
DEFECHO|
|
||||
#endif
|
||||
0xfee00000;
|
||||
|
||||
tios->c_line = N_IRDA;
|
||||
|
||||
tios->c_cc[VTIME] = 160;
|
||||
tios->c_cc[VMIN] = 137;
|
||||
tios->c_cc[VLNEXT] = 0xff;
|
||||
tios->c_cc[VSWTC] = 0x2a;
|
||||
|
||||
tios->c_ispeed = 3141592653U;
|
||||
tios->c_ospeed = 2718281828U;
|
||||
|
||||
return "{c_iflag=IGNBRK|IUTF8|0xdead0000, "
|
||||
"c_oflag=NL0|CR2|"
|
||||
#ifdef __alpha__
|
||||
"TAB3"
|
||||
#else
|
||||
"XTABS"
|
||||
#endif
|
||||
"|BS0|VT1|FF0|"
|
||||
#ifdef __alpha__
|
||||
"XTABS|"
|
||||
#endif
|
||||
"OPOST|ONLCR|OFILL|"
|
||||
#ifdef PAGEOUT
|
||||
"PAGEOUT|"
|
||||
#endif
|
||||
"0xbad00000, "
|
||||
"c_cflag=B75|B57600<<IBSHIFT|CS6|CSTOPB"
|
||||
#ifdef CTVB
|
||||
"|CTVB"
|
||||
#endif
|
||||
#ifdef CMSPAR
|
||||
"|CMSPAR"
|
||||
#endif
|
||||
", "
|
||||
"c_lflag=ISIG|ECHOE|FLUSHO|"
|
||||
#ifdef DEFECHO
|
||||
"DEFECHO|"
|
||||
#endif
|
||||
"0xfee00000, "
|
||||
#if VERBOSE
|
||||
"c_line=N_IRDA, "
|
||||
"c_cc[VMIN]=137, "
|
||||
"c_cc[VTIME]=160, "
|
||||
# if defined __alpha__
|
||||
"c_cc=[[VEOF] = 0, [VEOL] = 0, [VEOL2] = 0, "
|
||||
"[VERASE] = 0, [VWERASE] = 0, [VKILL] = 0, "
|
||||
"[VREPRINT] = 0x89, [VSWTC] = 0x2a, [VINTR] = 0, "
|
||||
"[VQUIT] = 0, [VSUSP] = 0, [VSTART] = 0, [VSTOP] = 0, "
|
||||
"[VLNEXT] = 0xff, [VDISCARD] = 0, [VMIN] = 0x89, "
|
||||
"[VTIME] = 0xa0, [17] = 0, [18] = 0]"
|
||||
# elif defined __mips__
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VDSUSP] = 0, "
|
||||
"[VREPRINT] = 0, [VDISCARD] = 0, [VWERASE] = 0, "
|
||||
"[VLNEXT] = 0xff, [VEOL2] = 0, [V_EOL] = 0, [18] = 0, "
|
||||
"[19] = 0, [20] = 0, [21] = 0, [22] = 0]"
|
||||
# elif defined __sparc__
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0x89, [VEOL] = 0xa0, "
|
||||
"[VEOL2] = 0, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VDSUSP] = 0, "
|
||||
"[VREPRINT] = 0, [VDISCARD] = 0, [VWERASE] = 0, "
|
||||
"[VLNEXT] = 0xff, [16] = 0, [17] = 0, [18] = 0]"
|
||||
# else
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VEOL] = 0, [VREPRINT] = 0, "
|
||||
"[VDISCARD] = 0, [VWERASE] = 0, [VLNEXT] = 0xff, "
|
||||
"[VEOL2] = 0, [17] = 0, [18] = 0]"
|
||||
#endif
|
||||
", c_ispeed=3141592653, c_ospeed=2718281828"
|
||||
#else /* !VERBOSE */
|
||||
"..."
|
||||
#endif /* VERBOSE */
|
||||
"}";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
setup_termios(void *tios_ptr, int variant)
|
||||
{
|
||||
struct termios *tios = tios_ptr;
|
||||
|
||||
switch (variant) {
|
||||
case 0:
|
||||
fill_memory(tios, sizeof(*tios));
|
||||
return NULL;
|
||||
|
||||
case 1:
|
||||
fill_memory_ex(tios, sizeof(*tios), 0xA5, 0x5A);
|
||||
return NULL;
|
||||
|
||||
case 2:
|
||||
memset(tios, 0, sizeof(*tios));
|
||||
|
||||
tios->c_iflag = IGNBRK|IUTF8|0xdead0000;
|
||||
tios->c_oflag = NL0|CR2|TAB3|BS0|VT1|FF0|
|
||||
#ifdef __alpha__
|
||||
XTABS|
|
||||
#endif
|
||||
OPOST|ONLCR|OFILL|
|
||||
#ifdef PAGEOUT
|
||||
PAGEOUT|
|
||||
#endif
|
||||
0xbad00000;
|
||||
tios->c_cflag = B75|(B57600<<IBSHIFT)|CS6|CSTOPB|
|
||||
#ifdef CTVB
|
||||
CTVB|
|
||||
#endif
|
||||
#ifdef CMSPAR
|
||||
CMSPAR|
|
||||
#endif
|
||||
0;
|
||||
tios->c_lflag = ISIG|ECHOE|FLUSHO|
|
||||
#ifdef DEFECHO
|
||||
DEFECHO|
|
||||
#endif
|
||||
0xfee00000;
|
||||
|
||||
tios->c_line = N_AX25;
|
||||
|
||||
tios->c_cc[VTIME] = 160;
|
||||
tios->c_cc[VMIN] = 137;
|
||||
tios->c_cc[VLNEXT] = 0xff;
|
||||
tios->c_cc[VSWTC] = 0x2a;
|
||||
|
||||
# if HAVE_STRUCT_TERMIOS_C_ISPEED
|
||||
tios->c_ispeed = 3141592653U;
|
||||
# endif
|
||||
# if HAVE_STRUCT_TERMIOS_C_OSPEED
|
||||
tios->c_ospeed = 2718281828U;
|
||||
# endif
|
||||
|
||||
return "{c_iflag=IGNBRK|IUTF8|0xdead0000, "
|
||||
"c_oflag=NL0|CR2|"
|
||||
#ifdef __alpha__
|
||||
"TAB3"
|
||||
#else
|
||||
"XTABS"
|
||||
#endif
|
||||
"|BS0|VT1|FF0|"
|
||||
#ifdef __alpha__
|
||||
"XTABS|"
|
||||
#endif
|
||||
"OPOST|ONLCR|OFILL|"
|
||||
#ifdef PAGEOUT
|
||||
"PAGEOUT|"
|
||||
#endif
|
||||
"0xbad00000, "
|
||||
"c_cflag=B75|B57600<<IBSHIFT|CS6|CSTOPB"
|
||||
#ifdef CTVB
|
||||
"|CTVB"
|
||||
#endif
|
||||
#ifdef CMSPAR
|
||||
"|CMSPAR"
|
||||
#endif
|
||||
", "
|
||||
"c_lflag=ISIG|ECHOE|FLUSHO|"
|
||||
#ifdef DEFECHO
|
||||
"DEFECHO|"
|
||||
#endif
|
||||
"0xfee00000, "
|
||||
#if VERBOSE
|
||||
"c_line=N_AX25, "
|
||||
"c_cc[VMIN]=137, "
|
||||
"c_cc[VTIME]=160, "
|
||||
# if defined __alpha__
|
||||
"c_cc=[[VEOF] = 0, [VEOL] = 0, [VEOL2] = 0, "
|
||||
"[VERASE] = 0, [VWERASE] = 0, [VKILL] = 0, "
|
||||
"[VREPRINT] = 0x89, [VSWTC] = 0x2a, [VINTR] = 0, "
|
||||
"[VQUIT] = 0, [VSUSP] = 0, [VSTART] = 0, [VSTOP] = 0, "
|
||||
"[VLNEXT] = 0xff, [VDISCARD] = 0, [VMIN] = 0x89, "
|
||||
"[VTIME] = 0xa0, [17] = 0, [18] = 0]"
|
||||
# elif defined __mips__
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VDSUSP] = 0, "
|
||||
"[VREPRINT] = 0, [VDISCARD] = 0, [VWERASE] = 0, "
|
||||
"[VLNEXT] = 0xff, [VEOL2] = 0, [V_EOL] = 0, [18] = 0, "
|
||||
"[19] = 0, [20] = 0, [21] = 0, [22] = 0]"
|
||||
# elif defined __powerpc__
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VMIN] = 0x89, "
|
||||
"[VEOL] = 0, [VTIME] = 0xa0, [VEOL2] = 0, "
|
||||
"[VSWTC] = 0x2a, [VWERASE] = 0, [VREPRINT] = 0, "
|
||||
"[VSUSP] = 0, [VSTART] = 0, [VSTOP] = 0, "
|
||||
"[VLNEXT] = 0xff, [VDISCARD] = 0, [17] = 0, [18] = 0]"
|
||||
# elif defined __sparc__
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0x89, [VEOL] = 0xa0, "
|
||||
"[VEOL2] = 0, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VDSUSP] = 0, "
|
||||
"[VREPRINT] = 0, [VDISCARD] = 0, [VWERASE] = 0, "
|
||||
"[VLNEXT] = 0xff, [16] = 0]"
|
||||
# else
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a, [VSTART] = 0, "
|
||||
"[VSTOP] = 0, [VSUSP] = 0, [VEOL] = 0, [VREPRINT] = 0, "
|
||||
"[VDISCARD] = 0, [VWERASE] = 0, [VLNEXT] = 0xff, "
|
||||
"[VEOL2] = 0, [17] = 0, [18] = 0]"
|
||||
#endif
|
||||
# if HAVE_STRUCT_TERMIOS_C_ISPEED
|
||||
", c_ispeed=3141592653"
|
||||
# endif
|
||||
# if HAVE_STRUCT_TERMIOS_C_OSPEED
|
||||
", c_ospeed=2718281828"
|
||||
# endif
|
||||
#else /* !VERBOSE */
|
||||
"..."
|
||||
#endif /* VERBOSE */
|
||||
"}";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
setup_termio(void *tios_ptr, int variant)
|
||||
{
|
||||
struct termio *tios = tios_ptr;
|
||||
|
||||
switch (variant) {
|
||||
case 0:
|
||||
fill_memory(tios, sizeof(*tios));
|
||||
return NULL;
|
||||
|
||||
case 1:
|
||||
fill_memory_ex(tios, sizeof(*tios), 0xA5, 0x5A);
|
||||
return NULL;
|
||||
|
||||
case 2:
|
||||
memset(tios, 0, sizeof(*tios));
|
||||
|
||||
tios->c_iflag = IGNBRK|IUTF8;
|
||||
tios->c_oflag = NL0|CR2|TAB3|BS0|VT1|FF0|
|
||||
#ifdef __alpha__
|
||||
XTABS|
|
||||
#endif
|
||||
OPOST|ONLCR|OFILL|
|
||||
#ifdef PAGEOUT
|
||||
PAGEOUT|
|
||||
#endif
|
||||
0;
|
||||
tios->c_cflag = B75|CS6|CSTOPB;
|
||||
tios->c_lflag = ISIG|ECHOE|FLUSHO|
|
||||
#ifdef DEFECHO
|
||||
DEFECHO|
|
||||
#endif
|
||||
0;
|
||||
|
||||
tios->c_line = 234;
|
||||
|
||||
#if defined __alpha__ || defined __powerpc__
|
||||
tios->c_cc[_VTIME] = 160;
|
||||
tios->c_cc[_VMIN] = 137;
|
||||
tios->c_cc[_VSWTC] = 0x2a;
|
||||
#else
|
||||
tios->c_cc[VTIME] = 160;
|
||||
tios->c_cc[VMIN] = 137;
|
||||
tios->c_cc[VSWTC] = 0x2a;
|
||||
#endif
|
||||
|
||||
return "{c_iflag=IGNBRK|IUTF8, "
|
||||
"c_oflag=NL0|CR2|"
|
||||
#ifdef __alpha__
|
||||
"TAB3"
|
||||
#else
|
||||
"XTABS"
|
||||
#endif
|
||||
"|BS0|VT1|FF0"
|
||||
#ifdef __alpha__
|
||||
"|XTABS"
|
||||
#endif
|
||||
"|OPOST|ONLCR|OFILL"
|
||||
#ifdef PAGEOUT
|
||||
"|PAGEOUT"
|
||||
#endif
|
||||
", "
|
||||
"c_cflag=B75|CS6|CSTOPB, "
|
||||
"c_lflag=ISIG|ECHOE|FLUSHO"
|
||||
#ifdef DEFECHO
|
||||
"|DEFECHO"
|
||||
#endif
|
||||
", "
|
||||
#if VERBOSE
|
||||
"c_line=0xea /* N_??? */, "
|
||||
# if defined __alpha__
|
||||
"c_cc[_VMIN]=137, "
|
||||
"c_cc[_VTIME]=160, "
|
||||
"c_cc=[[_VEOF] = 0, [_VEOL] = 0, [_VEOL2] = 0, "
|
||||
"[_VERASE] = 0, [_VWERASE] = 0, [_VKILL] = 0, "
|
||||
"[_VREPRINT] = 0x89, [_VSWTC] = 0x2a]"
|
||||
# elif defined __mips__
|
||||
"c_cc[VMIN]=137, "
|
||||
"c_cc[VTIME]=160, "
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a]"
|
||||
# elif defined __powerpc__
|
||||
"c_cc[_VMIN]=137, "
|
||||
"c_cc[_VTIME]=160, "
|
||||
"c_cc=[[_VINTR] = 0, [_VQUIT] = 0, [_VERASE] = 0, "
|
||||
"[_VKILL] = 0, [_VEOF] = 0, [_VMIN] = 0x89, "
|
||||
"[_VEOL] = 0, [_VTIME] = 0xa0, [_VEOL2] = 0, "
|
||||
"[_VSWTC] = 0x2a]"
|
||||
# elif defined __sparc__
|
||||
"c_cc[VMIN]=137, "
|
||||
"c_cc[VTIME]=160, "
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0x89, [VEOL] = 0xa0, "
|
||||
"[VEOL2] = 0, [VSWTC] = 0x2a]"
|
||||
# else
|
||||
"c_cc[VMIN]=137, "
|
||||
"c_cc[VTIME]=160, "
|
||||
"c_cc=[[VINTR] = 0, [VQUIT] = 0, [VERASE] = 0, "
|
||||
"[VKILL] = 0, [VEOF] = 0, [VTIME] = 0xa0, "
|
||||
"[VMIN] = 0x89, [VSWTC] = 0x2a]"
|
||||
#endif
|
||||
#else /* !VERBOSE */
|
||||
"..."
|
||||
#endif
|
||||
"}";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
struct termio *tio = tail_alloc(sizeof(*tio));
|
||||
struct termios *tios1 = tail_alloc(sizeof(*tios1));
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
struct termios2 *tios2 = tail_alloc(sizeof(*tios2));
|
||||
#endif
|
||||
|
||||
struct {
|
||||
struct {
|
||||
kernel_ulong_t cmd;
|
||||
const char *cmd_str;
|
||||
bool write;
|
||||
bool can_fail;
|
||||
} cmds[6];
|
||||
struct {
|
||||
kernel_ulong_t data;
|
||||
const char *data_str;
|
||||
bool valid;
|
||||
} args[4]; /* The last one should be valid */
|
||||
void (*printer)(void *data);
|
||||
const char * (*setup)(void *data, int variant);
|
||||
unsigned int setup_variants;
|
||||
} checks[] = {
|
||||
#ifdef HAVE_STRUCT_TERMIOS2
|
||||
{
|
||||
{
|
||||
{ ARG_STR(TCSETS2), true },
|
||||
{ ARG_STR(TCSETSW2), true },
|
||||
{ ARG_STR(TCSETSF2), true },
|
||||
{ ARG_STR(TCGETS2), false },
|
||||
},
|
||||
{
|
||||
{ (uintptr_t) ARG_STR(NULL), false },
|
||||
{ (uintptr_t) (tios2 + 1), NULL, false },
|
||||
{ (uintptr_t) tios2 + 4, NULL, false },
|
||||
{ (uintptr_t) tios2, NULL, true },
|
||||
},
|
||||
print_termios2, setup_termios2, 3
|
||||
},
|
||||
#endif
|
||||
{
|
||||
{
|
||||
/* XXX */
|
||||
{ TCSETS, "SNDCTL_TMR_START or TCSETS", true },
|
||||
{ TCSETSW, "SNDCTL_TMR_STOP or TCSETSW", true },
|
||||
{ TCSETSF, "SNDCTL_TMR_CONTINUE or TCSETSF",
|
||||
true },
|
||||
|
||||
{ ARG_STR(TCGETS), false },
|
||||
{ ARG_STR(TIOCSLCKTRMIOS), true, true },
|
||||
{ ARG_STR(TIOCGLCKTRMIOS), false, true },
|
||||
},
|
||||
{
|
||||
{ (uintptr_t) ARG_STR(NULL), false },
|
||||
{ (uintptr_t) (tios1 + 1), NULL, false },
|
||||
{ (uintptr_t) tios1 + 4, NULL, false },
|
||||
{ (uintptr_t) tios1, NULL, true },
|
||||
},
|
||||
print_termios, setup_termios, 3
|
||||
},
|
||||
{
|
||||
{
|
||||
{ ARG_STR(TCSETA), true },
|
||||
{ ARG_STR(TCSETAW), true },
|
||||
{ ARG_STR(TCSETAF), true },
|
||||
{ ARG_STR(TCGETA), false },
|
||||
},
|
||||
{
|
||||
{ (uintptr_t) ARG_STR(NULL), false },
|
||||
{ (uintptr_t) (tio + 1), NULL, false },
|
||||
{ (uintptr_t) tio + 4, NULL, false },
|
||||
{ (uintptr_t) tio, NULL, true },
|
||||
},
|
||||
print_termio, setup_termio, 3
|
||||
},
|
||||
};
|
||||
|
||||
ret = open("/dev/ptmx", O_RDWR|O_NOCTTY);
|
||||
if (ret < 0)
|
||||
perror_msg_and_skip("open(\"/dev/ptmx\")");
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(checks); i++) {
|
||||
const char *last_arg_str = NULL;
|
||||
|
||||
for (size_t j = 0; j < ARRAY_SIZE(checks[0].cmds); j++) {
|
||||
size_t k = 0, l = 0;
|
||||
bool end = false;
|
||||
bool write = checks[i].cmds[j].write;
|
||||
|
||||
if (!checks[i].cmds[j].cmd_str)
|
||||
continue;
|
||||
|
||||
while (true) {
|
||||
if (write && checks[i].args[k].valid)
|
||||
last_arg_str = checks[i].setup(
|
||||
(void *) (uintptr_t) (checks[i].args[k].data),
|
||||
l);
|
||||
|
||||
do_ioctl(checks[i].cmds[j].cmd,
|
||||
checks[i].cmds[j].cmd_str,
|
||||
ret,
|
||||
checks[i].printer,
|
||||
checks[i].args[k].data,
|
||||
checks[i].args[k].valid,
|
||||
write, last_arg_str,
|
||||
checks[i].cmds[j].can_fail);
|
||||
|
||||
if (k < (ARRAY_SIZE(checks[0].args) - 1))
|
||||
k++;
|
||||
else if (write && (l < checks[i].setup_variants))
|
||||
l++;
|
||||
else if (!write && (l < 1))
|
||||
l++;
|
||||
else
|
||||
end = true;
|
||||
|
||||
if (end)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts("+++ exited with 0 +++");
|
||||
|
||||
return 0;
|
||||
}
|
@ -133,6 +133,8 @@ ioctl_scsi
|
||||
ioctl_sg_io_v3
|
||||
ioctl_sg_io_v4
|
||||
ioctl_sock_gifconf
|
||||
ioctl_termios
|
||||
ioctl_termios-v
|
||||
ioctl_uffdio
|
||||
ioctl_v4l2
|
||||
ioperm
|
||||
|
@ -15,11 +15,15 @@ B9600
|
||||
B19200
|
||||
B38400
|
||||
B57600
|
||||
B76800
|
||||
B115200
|
||||
B153600
|
||||
B230400
|
||||
B307200
|
||||
B460800
|
||||
B500000
|
||||
B576000
|
||||
B614400
|
||||
B921600
|
||||
B1000000
|
||||
B1152000
|
||||
@ -31,3 +35,4 @@ B3500000
|
||||
B4000000
|
||||
EXTA
|
||||
EXTB
|
||||
BOTHER
|
||||
|
9
xlat/term_cflags.in
Normal file
9
xlat/term_cflags.in
Normal file
@ -0,0 +1,9 @@
|
||||
CSTOPB
|
||||
CREAD
|
||||
PARENB
|
||||
PARODD
|
||||
HUPCL
|
||||
CLOCAL
|
||||
CTVB /* VisioBraille Terminal flow control */
|
||||
CMSPAR /* mark or space (stick) parity */
|
||||
CRTSCTS /* flow control */
|
4
xlat/term_cflags_csize.in
Normal file
4
xlat/term_cflags_csize.in
Normal file
@ -0,0 +1,4 @@
|
||||
CS5
|
||||
CS6
|
||||
CS7
|
||||
CS8
|
15
xlat/term_iflags.in
Normal file
15
xlat/term_iflags.in
Normal file
@ -0,0 +1,15 @@
|
||||
IGNBRK /* Ignore break condition. */
|
||||
BRKINT /* Signal interrupt on break. */
|
||||
IGNPAR /* Ignore characters with parity errors. */
|
||||
PARMRK /* Mark parity and framing errors. */
|
||||
INPCK /* Enable input parity check. */
|
||||
ISTRIP /* Strip 8th bit off characters. */
|
||||
INLCR /* Map NL to CR on input. */
|
||||
IGNCR /* Ignore CR. */
|
||||
ICRNL /* Map CR to NL on input. */
|
||||
IUCLC /* Map upper case to lower case on input. */
|
||||
IXON /* Enable start/stop output control. */
|
||||
IXANY /* Any character will restart after stop. */
|
||||
IXOFF /* Enable start/stop input control. */
|
||||
IMAXBEL /* Ring bell when input queue is full. */
|
||||
IUTF8 /* Input is UTF-8 */
|
18
xlat/term_lflags.in
Normal file
18
xlat/term_lflags.in
Normal file
@ -0,0 +1,18 @@
|
||||
ISIG /* Enable signals. */
|
||||
ICANON /* Do erase and kill processing. */
|
||||
XCASE
|
||||
ECHO /* Enable echo. */
|
||||
ECHOE /* Visual erase for ERASE. */
|
||||
ECHOK /* Echo NL after KILL. */
|
||||
ECHONL /* Echo NL even if ECHO is off. */
|
||||
NOFLSH /* Disable flush after interrupt. */
|
||||
IEXTEN /* Enable DISCARD and LNEXT. */
|
||||
ECHOCTL /* Echo control characters as ^X. */
|
||||
ECHOPRT /* Hardcopy visual erase. */
|
||||
ECHOKE /* Visual erase for KILL. */
|
||||
FLUSHO
|
||||
PENDIN /* Retype pending input (state). */
|
||||
TOSTOP /* Send SIGTTOU for background output. */
|
||||
EXTPROC /* External processing on pty */
|
||||
|
||||
DEFECHO /* SUNOS thing, what is it? */
|
28
xlat/term_line_discs.in
Normal file
28
xlat/term_line_discs.in
Normal file
@ -0,0 +1,28 @@
|
||||
N_TTY 0
|
||||
N_SLIP 1
|
||||
N_MOUSE 2
|
||||
N_PPP 3
|
||||
N_STRIP 4
|
||||
N_AX25 5
|
||||
N_X25 6 /* X.25 async */
|
||||
N_6PACK 7
|
||||
N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
|
||||
N_R3964 9 /* Reserved for Simatic R3964 module */
|
||||
N_PROFIBUS_FDL 10 /* Reserved for Profibus */
|
||||
N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
|
||||
N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
|
||||
N_HDLC 13 /* synchronous HDLC */
|
||||
N_SYNC_PPP 14 /* synchronous PPP */
|
||||
N_HCI 15 /* Bluetooth HCI UART */
|
||||
N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */
|
||||
N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
|
||||
N_PPS 18 /* Pulse per Second */
|
||||
N_V253 19 /* Codec control over voice modem */
|
||||
N_CAIF 20 /* CAIF protocol for talking to modems */
|
||||
N_GSM0710 21 /* GSM 0710 Mux */
|
||||
N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */
|
||||
N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */
|
||||
N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */
|
||||
N_NCI 25 /* NFC NCI UART */
|
||||
N_SPEAKUP 26 /* Speakup communication with synths */
|
||||
N_NULL 27 /* Null ldisc used for error handling */
|
15
xlat/term_oflags.in
Normal file
15
xlat/term_oflags.in
Normal file
@ -0,0 +1,15 @@
|
||||
#ifdef ALPHA
|
||||
XTABS /* required by POSIX to == TAB3; but not on Alpha! */
|
||||
#endif
|
||||
|
||||
OPOST /* Perform output processing. */
|
||||
OLCUC /* Map lower case to upper case on output. */
|
||||
ONLCR /* Map NL to CR-NL on output. */
|
||||
OCRNL
|
||||
ONOCR
|
||||
ONLRET
|
||||
OFILL
|
||||
OFDEL
|
||||
|
||||
PAGEOUT /* SUNOS specific */
|
||||
WRAP /* SUNOS specific */
|
2
xlat/term_oflags_bsdly.in
Normal file
2
xlat/term_oflags_bsdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
BS1
|
||||
BS0
|
4
xlat/term_oflags_crdly.in
Normal file
4
xlat/term_oflags_crdly.in
Normal file
@ -0,0 +1,4 @@
|
||||
CR0
|
||||
CR1
|
||||
CR2
|
||||
CR3
|
2
xlat/term_oflags_ffdly.in
Normal file
2
xlat/term_oflags_ffdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
FF0
|
||||
FF1
|
4
xlat/term_oflags_nldly.in
Normal file
4
xlat/term_oflags_nldly.in
Normal file
@ -0,0 +1,4 @@
|
||||
NL0
|
||||
NL1
|
||||
NL2
|
||||
NL3
|
8
xlat/term_oflags_tabdly.in
Normal file
8
xlat/term_oflags_tabdly.in
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef ALPHA
|
||||
XTABS /* required by POSIX to == TAB3; but not on Alpha! */
|
||||
#endif
|
||||
|
||||
TAB0
|
||||
TAB1
|
||||
TAB2
|
||||
TAB3
|
2
xlat/term_oflags_vtdly.in
Normal file
2
xlat/term_oflags_vtdly.in
Normal file
@ -0,0 +1,2 @@
|
||||
VT0
|
||||
VT1
|
10
xlat/termio_cc.in
Normal file
10
xlat/termio_cc.in
Normal file
@ -0,0 +1,10 @@
|
||||
_VINTR
|
||||
_VQUIT
|
||||
_VERASE
|
||||
_VKILL
|
||||
_VEOF
|
||||
_VMIN
|
||||
_VEOL
|
||||
_VTIME
|
||||
_VEOL2
|
||||
_VSWTC
|
18
xlat/termios_cc.in
Normal file
18
xlat/termios_cc.in
Normal file
@ -0,0 +1,18 @@
|
||||
VINTR /* Interrupt character [ISIG]. */
|
||||
VQUIT /* Quit character [ISIG]. */
|
||||
VERASE /* Erase character [ICANON]. */
|
||||
VKILL /* Kill-line character [ICANON]. */
|
||||
VEOL2 /* Second EOL character [ICANON]. */
|
||||
VSWTC /* ??? */
|
||||
VSTART /* Start (X-ON) character [IXON, IXOFF]. */
|
||||
VSTOP /* Stop (X-OFF) character [IXON, IXOFF]. */
|
||||
VSUSP /* Suspend character [ISIG]. */
|
||||
VDSUSP /* Delayed suspend character [ISIG]. */
|
||||
VREPRINT /* Reprint-line character [ICANON]. */
|
||||
VDISCARD /* Discard character [IEXTEN]. */
|
||||
VWERASE /* Word-erase character [ICANON]. */
|
||||
VLNEXT /* Literal-next character [IEXTEN]. */
|
||||
VEOF /* End-of-file character [ICANON]. */
|
||||
VEOL /* End-of-line character [ICANON]. */
|
||||
VMIN /* Minimum number of bytes read at once [!ICANON]. */
|
||||
VTIME /* Time-out value (tenths of a second) [!ICANON]. */
|
Loading…
Reference in New Issue
Block a user