lkml.org 
[lkml]   [2006]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Subject[TEST SUITE] termios: basic test set for the new termios code
From
Date
Please send any updates/extra test cases to me.

/*
* Test suite for the new termios functions
*
* gcc -iquote kernel-src/include/asm-x86_64 test-suite.c -o ./ts
*/

#include "termbits.h"
#include "termios.h"
#include "ioctls.h"

#define TCGETS2 _IOR('T',0x2A, struct termios2)
#define TCSETS2 _IOW('T',0x2B, struct termios2)
#define TCSETSW2 _IOW('T',0x2C, struct termios2)
#define TCSETSF2 _IOW('T',0x2D, struct termios2)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

static int compare_termios_11(struct termios *a, struct termios *b)
{
int diff = 0;

if(a->c_iflag != b->c_iflag) {
printf("Iflag change of %04X\n", a->c_iflag ^ b->c_iflag);
diff = 1;
}
if(a->c_oflag != b->c_oflag) {
printf("Oflag change of %04X\n", a->c_oflag ^ b->c_oflag);
diff = 1;
}
if(a->c_cflag != b->c_cflag) {
printf("Iflag change of %04X\n", a->c_cflag ^ b->c_cflag);
diff = 1;
}
if(a->c_lflag != b->c_lflag) {
printf("Iflag change of %04X\n", a->c_lflag ^ b->c_lflag);
diff = 1;
}
if(a->c_line != b->c_line) {
printf("Line differs %02X v %02X\n", a->c_line, b->c_line);
diff = 1;
}
#ifdef NCC_V1
if(memcmp(a->c_cc, b->c_cc, NCC_V1)) {
#else
if(memcmp(a->c_cc, b->c_cc, NCC)) {
#endif
printf("CC differs.\n");
diff = 1;
}
return diff;
}

static int compare_termios_12(struct termios *a, struct termios2 *b)
{
int diff = 0;

if(a->c_iflag != b->c_iflag) {
printf("Iflag change of %04X\n", a->c_iflag ^ b->c_iflag);
diff = 1;
}
if(a->c_oflag != b->c_oflag) {
printf("Oflag change of %04X\n", a->c_oflag ^ b->c_oflag);
diff = 1;
}
if(a->c_cflag != b->c_cflag) {
printf("Iflag change of %04X\n", a->c_cflag ^ b->c_cflag);
diff = 1;
}
if(a->c_lflag != b->c_lflag) {
printf("Iflag change of %04X\n", a->c_lflag ^ b->c_lflag);
diff = 1;
}
if(a->c_line != b->c_line) {
printf("Line differs %02X v %02X\n", a->c_line, b->c_line);
diff = 1;
}
#ifdef NCC_V1
if(memcmp(a->c_cc, b->c_cc, NCC_V1)) {
#else
if(memcmp(a->c_cc, b->c_cc, NCC)) {
#endif
printf("CC differs.\n");
diff = 1;
}
return diff;
}

static int compare_termios_22(struct termios2 *a, struct termios2 *b)
{
int diff = 0;

if(a->c_iflag != b->c_iflag) {
printf("Iflag change of %04X\n", a->c_iflag ^ b->c_iflag);
diff = 1;
}
if(a->c_oflag != b->c_oflag) {
printf("Oflag change of %04X\n", a->c_oflag ^ b->c_oflag);
diff = 1;
}
if(a->c_cflag != b->c_cflag) {
printf("Iflag change of %04X\n", a->c_cflag ^ b->c_cflag);
diff = 1;
}
if(a->c_lflag != b->c_lflag) {
printf("Iflag change of %04X\n", a->c_lflag ^ b->c_lflag);
diff = 1;
}
if(a->c_line != b->c_line) {
printf("Line differs %02X v %02X\n", a->c_line, b->c_line);
diff = 1;
}
if(memcmp(a->c_cc, b->c_cc, NCC)) {
printf("CC differs.\n");
diff = 1;
}
if(a->c_ispeed != b->c_ispeed) {
printf("Ispeed differs %d v %d\n", a->c_ispeed, b->c_ispeed);
diff = 1;
}
if(a->c_ospeed != b->c_ospeed) {
printf("Ospeed differs %d v %d\n", a->c_ospeed, b->c_ospeed);
diff = 1;
}
return diff;
}


struct padcheck1
{
struct termios a;
unsigned int cookie;
};

struct padcheck2
{
struct termios2 a;
unsigned int cookie;
};


static void do_check_no_overrun(int fd, unsigned int cookie)
{
static struct padcheck1 t1;
static struct padcheck2 t2;

t1.cookie = cookie;
t2.cookie = cookie;
t2.a.c_ospeed = cookie;

if(ioctl(fd, TCGETS, &t1) < 0) {
perror("ioctl");
exit(1);
}

if(t1.cookie != cookie) {
printf("FAIL: TCGETS scribbled on cookie.\n");
exit(1);
}

if(ioctl(fd, TCGETS2, &t2) < 0) {
perror("ioctl");
fprintf(stderr, "This kernel does not appear to support extended termios.\n");
exit(1);
}

if(t2.cookie != cookie) {
printf("FAIL: TCGETS2 scribbled on cookie.\n");
exit(1);
}

if(t2.a.c_ospeed == cookie) {
printf("FAIL: TCGETS2 read appears short.\n");
exit(1);
}

if(compare_termios_12(&t1.a, &t2.a)) {
printf("FAIL: TCGETS and TCGETS2 disagree on common data.\n");
exit(1);
}
printf("PASS: Basic scribble test.\n");
}

static void test_functions(int fd)
{
struct termios2 t1;
struct termios2 t2;
struct termios t1_v1;

if(ioctl(fd, TCGETS2, &t1) < 0) {
perror("ioctl");
exit(1);
}
printf("Initial ospeed %d\n", t1.c_ospeed);
t1.c_ospeed = 12345;
t1.c_cflag &= ~CBAUD;
t1.c_cflag |= BOTHER;

if(ioctl(fd, TCSETS2, &t1) < 0) {
perror("ioctl");
printf("FAIL: unsupported speed should not error\n");
exit(1);
}

/* Get the actual values set: May differ */
if(ioctl(fd, TCGETS2, &t2) < 0) {
perror("ioctl");
exit(1);
}

/* May be differences to report but are ok */
compare_termios_22(&t1, &t2);

if(ioctl(fd, TCGETS2, &t1) < 0) {
perror("ioctl");
exit(1);
}

if(compare_termios_22(&t1, &t2)) {
printf("FAIL: Repeating TCGETS gives different result.\n");
exit(1);
}

if(ioctl(fd, TCGETS, &t1_v1) < 0) {
perror("ioctl");
exit(1);
}

if(compare_termios_12(&t1_v1, &t2)) {
printf("FAIL: Repeating TCGETS in old form gives different result.\n");
exit(1);
}

if(ioctl(fd, TCSETS2, &t1) < 0) {
perror("ioctl");
printf("FAIL: settings provided by terminal should not fail on set.\n");
exit(1);
}

if(ioctl(fd, TCGETS, &t1_v1) < 0) {
perror("ioctl");
exit(1);
}

if(ioctl(fd, TCGETS2, &t2) < 0) {
perror("ioctl");
exit(1);
}

/* Differences are bad because this is using the settings the tty said were ok */
if (compare_termios_22(&t1, &t2)) {
printf("FAIL: fetched settings differ from set ones yet were tty provided.\n");
exit(1);
}

if (compare_termios_12(&t1_v1, &t1)) {
printf("FAIL: old ioctl settings differ from set ones yet were tty provided and new setting agreed.\n");
exit(1);
}

if(t1.c_ospeed != 12345) {
printf("SKIP: Tests that may need a pty.\n");
return;
}

if(t1_v1.c_cflag & BOTHER)
printf("t1_v1 BOTHER - OK");
/* Now see what occurs if we set an old style and get new style, speed should
be preserved. */

if(ioctl(fd, TCSETS, &t1_v1) < 0) {
perror("ioctl");
exit(1);
}

if(ioctl(fd, TCGETS2, &t2) < 0) {
perror("ioctl");
exit(1);
}

if(t2.c_ospeed != 12345) {
printf("FAIL: setting old style termios disturbed extended speed.\n");
printf("SPEED: %d\n", t2.c_ospeed);
exit(1);
}

/* Now try the reverse */

t1_v1.c_cflag &= ~CBAUD;
t1_v1.c_cflag |= B9600;

if(ioctl(fd, TCSETS, &t1_v1) < 0) {
perror("ioctl");
exit(1);
}

if(ioctl(fd, TCGETS2, &t2) < 0) {
perror("ioctl");
exit(1);
}

if(t2.c_ospeed != 9600) {
printf("FAIL: speed was not reset by old style termios set.\n");
exit(1);
}

}


int main(int argc, char *argv[])
{
int fd;
if(argc != 2) {
fprintf(stderr, "%s: [ttypath].\n", argv[0]);
exit(1);
}

fd = open(argv[1], O_RDWR);
if(fd == -1) {
perror(argv[1]);
exit(1);
}

do_check_no_overrun(fd, 0xA5A5A5A5);
do_check_no_overrun(fd, 0x5A5A5A5A);
test_functions(fd);

printf("PASS\n");
exit(0);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-11-08 21:35    [W:0.039 / U:0.348 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site