source: rtems/testsuites/libtests/termios01/init.c @ 4ac5ffbb

5
Last change on this file since 4ac5ffbb was 2c12262, checked in by Sebastian Huber <sebastian.huber@…>, on 11/28/17 at 05:30:35

termios: Use self-contained objects

Update #2840.

  • Property mode set to 100644
File size: 24.5 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2010.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include "tmacros.h"
15#define TTYDEFCHARS
16#include <termios.h>
17#include <rtems/libcsupport.h>
18#include <rtems/malloc.h>
19#include <rtems/termiostypes.h>
20#include <fcntl.h>
21#include <limits.h>
22#include <unistd.h>
23#include <sys/errno.h>
24#include <sys/stat.h>
25
26const char rtems_test_name[] = "TERMIOS 1";
27
28/* rtems_termios_baud_t is a typedefs to int32_t */
29#define PRIdrtems_termios_baud_t PRId32
30
31/*
32 *  Termios Test Driver
33 */
34#include "termios_testdriver.h"
35
36static const rtems_driver_address_table test_driver =
37  TERMIOS_TEST_DRIVER_TABLE_ENTRY;
38
39/*
40 *  Baud Rate Constant Mapping Entry
41 */
42typedef struct {
43  tcflag_t constant;
44  rtems_termios_baud_t baud;
45} termios_baud_test_r;
46
47#define INVALID_CONSTANT ((tcflag_t) -2)
48
49#define INVALID_BAUD ((rtems_termios_baud_t) -2)
50/*
51 *  Baud Rate Constant Mapping Table
52 */
53static const termios_baud_test_r baud_table[] = {
54  { B0,           0 },
55  { B50,         50 },
56  { B75,         75 },
57  { B110,       110 },
58  { B134,       134 },
59  { B150,       150 },
60  { B200,       200 },
61  { B300,       300 },
62  { B600,       600 },
63  { B1200,     1200 },
64  { B1800,     1800 },
65  { B2400,     2400 },
66  { B4800,     4800 },
67  { B9600,     9600 },
68  { B19200,   19200 },
69  { B38400,   38400 },
70  { B7200,     7200 },
71  { B14400,   14400 },
72  { B28800,   28800 },
73  { B57600,   57600 },
74  { B76800,   76800 },
75  { B115200, 115200 },
76  { B230400, 230400 },
77  { B460800, 460800 },
78  { B921600, 921600 },
79  { INVALID_CONSTANT, INVALID_BAUD }
80};
81
82/*
83 *  Character Size Constant Mapping Entry
84 */
85typedef struct {
86  tcflag_t constant;
87  int bits;
88} termios_character_size_test_r;
89
90/*
91 *  Character Size Constant Mapping Table
92 */
93static const termios_character_size_test_r char_size_table[] = {
94  { CS5,      5 },
95  { CS6,      6 },
96  { CS7,      7 },
97  { CS8,      8 },
98  { INVALID_CONSTANT, -1 }
99};
100
101/*
102 *  Parity Constant Mapping Entry
103 */
104typedef struct {
105  tcflag_t constant;
106  const char *parity;
107} termios_parity_test_r;
108
109/*
110 *  Parity Constant Mapping Table
111 */
112static const termios_parity_test_r parity_table[] = {
113  { 0,                "none" },
114  { PARENB,           "even" },
115  { PARENB | PARODD,  "odd" },
116  { INVALID_CONSTANT, NULL }
117};
118
119/*
120 *  Stop Bit Constant Mapping Entry
121 */
122typedef struct {
123  tcflag_t constant;
124  int stop;
125} termios_stop_bits_test_r;
126
127/*
128 *  Stop Bit Constant Mapping Table
129 */
130static const termios_stop_bits_test_r stop_bits_table[] = {
131  { 0,       1 },
132  { CSTOPB,  2 },
133  { INVALID_CONSTANT, -1 }
134};
135
136/*
137 *  Test converting baud rate into an index
138 */
139static void test_termios_baud2index(void)
140{
141  int i;
142  int index;
143
144  puts( "Test termios_baud2index..." );
145  puts( "termios_baud_to_index(-2) - NOT OK" );
146  i = rtems_termios_baud_to_index( INVALID_CONSTANT );
147  rtems_test_assert( i == -1 );
148
149  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
150    printf(
151      "termios_baud_to_index(B%" PRIdrtems_termios_baud_t ") - OK\n",
152      baud_table[i].baud
153    );
154    index = rtems_termios_baud_to_index( baud_table[i].constant );
155    if ( index != i ) {
156      printf( "ERROR - returned %d should be %d\n", index, i );
157      rtems_test_exit(0);
158    }
159  }
160}
161
162/*
163 *  Test converting termios baud constant to baud number
164 */
165static void test_termios_baud2number(void)
166{
167  int i;
168  rtems_termios_baud_t number;
169
170  puts(
171    "\n"
172    "Test termios_baud2number..."
173  );
174  puts( "termios_baud_to_number(-2) - NOT OK" );
175  number = rtems_termios_baud_to_number( INVALID_CONSTANT );
176  rtems_test_assert( number == 0 );
177
178  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
179    printf(
180      "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n",
181      baud_table[i].baud
182    );
183    number = rtems_termios_baud_to_number( baud_table[i].constant );
184    if ( number != baud_table[i].baud ) {
185      printf(
186        "ERROR - returned %" PRIdrtems_termios_baud_t
187        " should be %" PRIdrtems_termios_baud_t "\n",
188        number,
189        baud_table[i].baud
190      );
191      rtems_test_exit(0);
192    }
193  }
194}
195
196/*
197 *  Test converting baud number to termios baud constant
198 */
199static void test_termios_number_to_baud(void)
200{
201  int i;
202  tcflag_t termios_baud;
203
204  puts(
205    "\n"
206    "Test termios_number_to_baud..."
207  );
208  puts( "termios_number_to_baud(-2) - NOT OK" );
209  termios_baud = rtems_termios_number_to_baud( INVALID_BAUD );
210  rtems_test_assert( termios_baud == 0 );
211
212  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
213    printf(
214      "termios_number_to_baud(B%" PRIdrtems_termios_baud_t ") - OK\n",
215      baud_table[i].baud
216    );
217    termios_baud = rtems_termios_number_to_baud( baud_table[i].baud );
218    if ( termios_baud != baud_table[i].constant ) {
219      printf(
220        "ERROR - returned %d should be %d\n",
221        termios_baud,
222        baud_table[i].constant
223      );
224      rtems_test_exit(0);
225    }
226  }
227}
228
229/*
230 *  Test all the baud rate options
231 */
232static void test_termios_set_baud(
233  int test
234)
235{
236  int             sc;
237  int             i;
238  struct termios  attr;
239
240  puts( "Test termios setting device baud rate..." );
241  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
242    sc = tcgetattr( test, &attr );
243    if ( sc != 0 ) {
244      printf( "ERROR - return %d\n", sc );
245      rtems_test_exit(0);
246    }
247
248    attr.c_ispeed = baud_table[i].constant;
249    attr.c_ospeed = baud_table[i].constant;
250
251    printf(
252      "tcsetattr(TCSANOW, B%" PRIdrtems_termios_baud_t ") - OK\n",
253      baud_table[i].baud
254    );
255    sc = tcsetattr( test, TCSANOW, &attr );
256    if ( sc != 0 ) {
257      printf( "ERROR - return %d\n", sc );
258      rtems_test_exit(0);
259    }
260
261    printf(
262      "tcsetattr(TCSADRAIN, B%" PRIdrtems_termios_baud_t ") - OK\n",
263      baud_table[i].baud
264    );
265    sc = tcsetattr( test, TCSADRAIN, &attr );
266    if ( sc != 0 ) {
267      printf( "ERROR - return %d\n", sc );
268      rtems_test_exit(0);
269    }
270
271    printf(
272      "tcsetattr(TCSAFLUSH, B%" PRIdrtems_termios_baud_t ") - OK\n",
273      baud_table[i].baud
274    );
275    sc = tcsetattr( test, TCSAFLUSH, &attr );
276    if ( sc != 0 ) {
277      printf( "ERROR - return %d\n", sc );
278      rtems_test_exit(0);
279    }
280  }
281}
282
283/*
284 *  Test all the character size options
285 */
286static void test_termios_set_charsize(
287  int test
288)
289{
290  int             sc;
291  int             i;
292  struct termios  attr;
293
294  puts(
295    "\n"
296    "Test termios setting device character size ..."
297  );
298  for (i=0 ; char_size_table[i].constant != INVALID_CONSTANT ; i++ ) {
299    tcflag_t csize = CSIZE;
300
301    sc = tcgetattr( test, &attr );
302    if ( sc != 0 ) {
303      printf( "ERROR - return %d\n", sc );
304      rtems_test_exit(0);
305    }
306
307    attr.c_cflag &= ~csize;
308    attr.c_cflag |= char_size_table[i].constant;
309
310    printf( "tcsetattr(TCSANOW, CS%d) - OK\n", char_size_table[i].bits );
311    sc = tcsetattr( test, TCSANOW, &attr );
312    if ( sc != 0 ) {
313      printf( "ERROR - return %d\n", sc );
314      rtems_test_exit(0);
315    }
316
317    printf( "tcsetattr(TCSADRAIN, CS%d) - OK\n", char_size_table[i].bits );
318    sc = tcsetattr( test, TCSADRAIN, &attr );
319    if ( sc != 0 ) {
320      printf( "ERROR - return %d\n", sc );
321      rtems_test_exit(0);
322    }
323
324    printf( "tcsetattr(TCSAFLUSH, CS%d) - OK\n", char_size_table[i].bits );
325    sc = tcsetattr( test, TCSAFLUSH, &attr );
326    if ( sc != 0 ) {
327      printf( "ERROR - return %d\n", sc );
328      rtems_test_exit(0);
329    }
330
331    printf( "tcsetattr(TCSASOFT, CS%d) - OK\n", char_size_table[i].bits );
332    sc = tcsetattr( test, TCSASOFT, &attr );
333    if ( sc != 0 ) {
334      printf( "ERROR - return %d\n", sc );
335      rtems_test_exit(0);
336    }
337  }
338}
339
340/*
341 *  Test all the parity options
342 */
343static void test_termios_set_parity(
344  int test
345)
346{
347  int             sc;
348  int             i;
349  struct termios  attr;
350
351  puts(
352    "\n"
353    "Test termios setting device parity ..."
354  );
355  for (i=0 ; parity_table[i].constant != INVALID_CONSTANT ; i++ ) {
356    tcflag_t par = PARENB | PARODD;
357
358    sc = tcgetattr( test, &attr );
359    if ( sc != 0 ) {
360      printf( "ERROR - return %d\n", sc );
361      rtems_test_exit(0);
362    }
363
364    attr.c_cflag &= ~par;
365    attr.c_cflag |= parity_table[i].constant;
366
367    printf( "tcsetattr(TCSANOW, %s) - OK\n", parity_table[i].parity );
368    sc = tcsetattr( test, TCSANOW, &attr );
369    if ( sc != 0 ) {
370      printf( "ERROR - return %d\n", sc );
371      rtems_test_exit(0);
372    }
373
374    printf( "tcsetattr(TCSADRAIN, %s) - OK\n", parity_table[i].parity );
375    sc = tcsetattr( test, TCSADRAIN, &attr );
376    if ( sc != 0 ) {
377      printf( "ERROR - return %d\n", sc );
378      rtems_test_exit(0);
379    }
380
381    printf( "tcsetattr(TCSAFLUSH, %s) - OK\n", parity_table[i].parity );
382    sc = tcsetattr( test, TCSAFLUSH, &attr );
383    if ( sc != 0 ) {
384      printf( "ERROR - return %d\n", sc );
385      rtems_test_exit(0);
386    }
387
388    printf( "tcsetattr(TCSASOFT, %s) - OK\n", parity_table[i].parity );
389    sc = tcsetattr( test, TCSASOFT, &attr );
390    if ( sc != 0 ) {
391      printf( "ERROR - return %d\n", sc );
392      rtems_test_exit(0);
393    }
394  }
395}
396
397/*
398 *  Test all the stop bit options
399 */
400static void test_termios_set_stop_bits(
401  int test
402)
403{
404  int             sc;
405  int             i;
406  struct termios  attr;
407
408  puts(
409    "\n"
410    "Test termios setting device character size ..."
411  );
412  for (i=0 ; stop_bits_table[i].constant != INVALID_CONSTANT ; i++ ) {
413    tcflag_t cstopb = CSTOPB;
414
415    sc = tcgetattr( test, &attr );
416    if ( sc != 0 ) {
417      printf( "ERROR - return %d\n", sc );
418      rtems_test_exit(0);
419    }
420
421    attr.c_cflag &= ~cstopb;
422    attr.c_cflag |= stop_bits_table[i].constant;
423
424    printf( "tcsetattr(TCSANOW, %d bit%s) - OK\n",
425      stop_bits_table[i].stop,
426      ((stop_bits_table[i].stop == 1) ? "" : "s")
427    );
428    sc = tcsetattr( test, TCSANOW, &attr );
429    if ( sc != 0 ) {
430      printf( "ERROR - return %d\n", sc );
431      rtems_test_exit(0);
432    }
433
434    printf( "tcsetattr(TCSADRAIN, %d bits) - OK\n", stop_bits_table[i].stop );
435    sc = tcsetattr( test, TCSADRAIN, &attr );
436    if ( sc != 0 ) {
437      printf( "ERROR - return %d\n", sc );
438      rtems_test_exit(0);
439    }
440
441    printf( "tcsetattr(TCSAFLUSH, %d bits) - OK\n", stop_bits_table[i].stop );
442    sc = tcsetattr( test, TCSAFLUSH, &attr );
443    if ( sc != 0 ) {
444      printf( "ERROR - return %d\n", sc );
445      rtems_test_exit(0);
446    }
447
448    printf( "tcsetattr(TCSASOFT, %d bits) - OK\n", stop_bits_table[i].stop );
449    sc = tcsetattr( test, TCSASOFT, &attr );
450    if ( sc != 0 ) {
451      printf( "ERROR - return %d\n", sc );
452      rtems_test_exit(0);
453    }
454  }
455}
456
457static void test_termios_cfoutspeed(void)
458{
459  int i;
460  int sc;
461  speed_t speed;
462  struct termios term;
463  speed_t bad;
464
465  bad = B921600 << 1;
466  memset( &term, '\0', sizeof(term) );
467  puts( "cfsetospeed(BAD BAUD) - EINVAL" );
468  sc = cfsetospeed( &term, bad );
469  rtems_test_assert( sc == -1 );
470  rtems_test_assert( errno == EINVAL );
471
472  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
473    memset( &term, '\0', sizeof(term) );
474    printf(
475      "cfsetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
476      baud_table[i].baud
477    );
478    sc = cfsetospeed( &term, baud_table[i].constant );
479    rtems_test_assert( !sc );
480    printf(
481      "cfgetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
482      baud_table[i].baud
483    );
484    speed = cfgetospeed( &term );
485    rtems_test_assert( speed == baud_table[i].constant );
486  }
487}
488
489static void test_termios_cfinspeed(void)
490{
491  int             i;
492  int             sc;
493  speed_t         speed;
494  struct termios  term;
495  speed_t         bad;
496
497  bad = B921600 << 1;
498  memset( &term, '\0', sizeof(term) );
499  puts( "cfsetispeed(BAD BAUD) - EINVAL" );
500  sc = cfsetispeed( &term, bad );
501  rtems_test_assert( sc == -1 );
502  rtems_test_assert( errno == EINVAL );
503
504  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
505    memset( &term, '\0', sizeof(term) );
506    printf(
507      "cfsetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
508      baud_table[i].baud
509    );
510    sc = cfsetispeed( &term, baud_table[i].constant );
511    rtems_test_assert( !sc );
512
513    printf(
514      "cfgetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
515      baud_table[i].baud
516    );
517    speed = cfgetispeed( &term );
518    rtems_test_assert( speed == baud_table[i].constant );
519  }
520}
521
522static void test_termios_cfsetspeed(void)
523{
524  int             i;
525  int             status;
526  speed_t         speed;
527  struct termios  term;
528  speed_t         bad;
529
530  bad = B921600 << 1;
531  memset( &term, '\0', sizeof(term) );
532  puts( "cfsetspeed(BAD BAUD) - EINVAL" );
533  status = cfsetspeed( &term, bad );
534  rtems_test_assert( status == -1 );
535  rtems_test_assert( errno == EINVAL );
536
537  for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
538    memset( &term, '\0', sizeof(term) );
539    printf(
540      "cfsetspeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
541      baud_table[i].baud
542    );
543    status = cfsetspeed( &term, baud_table[i].constant );
544    rtems_test_assert( !status );
545
546    printf(
547      "cfgetspeed(B%" PRIdrtems_termios_baud_t ") - checking both inspeed and outspeed - OK\n",
548      baud_table[i].baud
549    );
550    speed = cfgetispeed( &term );
551    rtems_test_assert( speed == baud_table[i].constant );
552
553    speed = cfgetospeed( &term );
554    rtems_test_assert( speed == baud_table[i].constant );
555  }
556}
557
558static void test_termios_cfmakeraw(void)
559{
560  struct termios  term;
561
562  memset( &term, '\0', sizeof(term) );
563  cfmakeraw( &term );
564  puts( "cfmakeraw - OK" );
565
566  /* Check that all of the flags were set correctly */
567  rtems_test_assert( ~(term.c_iflag & (IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR)) );
568
569  rtems_test_assert( term.c_iflag & (IGNBRK) );
570
571  rtems_test_assert( ~(term.c_oflag & OPOST) );
572
573  rtems_test_assert( ~(term.c_lflag & (ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN)) );
574
575  rtems_test_assert( ~(term.c_cflag & (CSIZE|PARENB)) );
576
577  rtems_test_assert( term.c_cflag & (CS8|CREAD) );
578
579  rtems_test_assert( term.c_cc[VMIN] == 1 );
580
581  rtems_test_assert( term.c_cc[VTIME] == 0 );
582}
583
584static void test_termios_cfmakesane(void)
585{
586  struct termios  term;
587
588  memset( &term, '\0', sizeof(term) );
589  cfmakesane( &term );
590  puts( "cfmakesane - OK" );
591
592  /* Check that all of the flags were set correctly */
593  rtems_test_assert( term.c_iflag == TTYDEF_IFLAG );
594
595  rtems_test_assert( term.c_oflag == TTYDEF_OFLAG );
596
597  rtems_test_assert( term.c_lflag == TTYDEF_LFLAG );
598
599  rtems_test_assert( term.c_cflag == TTYDEF_CFLAG );
600
601  rtems_test_assert( term.c_ispeed == TTYDEF_SPEED );
602
603  rtems_test_assert( term.c_ospeed == TTYDEF_SPEED );
604
605  rtems_test_assert( memcmp(&term.c_cc, ttydefchars, sizeof(term.c_cc)) == 0 );
606}
607
608typedef struct {
609  rtems_termios_device_context base;
610  bool done;
611} device_context;
612
613static rtems_status_code test_early_device_install(
614  rtems_device_major_number major,
615  rtems_device_minor_number minor,
616  void *arg
617)
618{
619  static const rtems_termios_device_handler handler;
620  static const char dev[] = "/foobar";
621
622  rtems_resource_snapshot snapshot;
623  rtems_status_code sc;
624  int fd;
625  int rv;
626  int i;
627
628  rtems_resource_snapshot_take( &snapshot );
629
630  sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL );
631  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
632
633  /*
634   * The loop ensures that file descriptor 0 is the first free file descriptor
635   * after this test case.
636   */
637  for (i = 0; i < 4; ++i) {
638    fd = open( &dev[0], O_RDWR );
639    rtems_test_assert( fd == i );
640
641    rv = close( fd );
642    rtems_test_assert( rv == 0 );
643  }
644
645  rv = unlink( &dev[0] );
646  rtems_test_assert( rv == 0 );
647
648  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
649
650  return RTEMS_SUCCESSFUL;
651}
652
653static void test_device_install_remove(void)
654{
655  static const rtems_termios_device_handler handler;
656  static const char dev[] = "/foobar";
657
658  rtems_resource_snapshot snapshot;
659  rtems_status_code sc;
660  void *greedy;
661  int rv;
662
663  rtems_resource_snapshot_take( &snapshot );
664
665  greedy = rtems_heap_greedy_allocate( NULL, 0 );
666
667  sc = rtems_termios_device_install( "/", &handler, NULL, NULL );
668  rtems_test_assert( sc == RTEMS_NO_MEMORY );
669
670  rtems_heap_greedy_free( greedy );
671
672  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
673
674  sc = rtems_termios_device_install( "/", &handler, NULL, NULL );
675  rtems_test_assert( sc == RTEMS_UNSATISFIED );
676
677  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
678
679  sc = rtems_termios_device_install( &dev[0], &handler, NULL, NULL );
680  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
681
682  rv = unlink( &dev[0] );
683  rtems_test_assert( rv == 0 );
684
685  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
686}
687
688static bool first_open_error(
689  rtems_termios_tty *tty,
690  rtems_termios_device_context *base,
691  struct termios *term,
692  rtems_libio_open_close_args_t *args
693)
694{
695  device_context *ctx = (device_context *) base;
696
697  (void) tty;
698  (void) term;
699  (void) args;
700
701  ctx->done = true;
702
703  return false;
704}
705
706static void test_first_open_error(void)
707{
708  static const rtems_termios_device_handler handler = {
709    .first_open = first_open_error
710  };
711  static const char dev[] = "/foobar";
712
713  rtems_resource_snapshot snapshot;
714  rtems_status_code sc;
715  int fd;
716  int rv;
717  device_context ctx = {
718    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
719    .done = false
720  };
721
722  rtems_resource_snapshot_take( &snapshot );
723
724  sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base );
725  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
726
727  rtems_test_assert( !ctx.done );
728  errno = 0;
729  fd = open( &dev[0], O_RDWR );
730  rtems_test_assert( fd == -1 );
731  rtems_test_assert( errno == ENOMEM );
732  rtems_test_assert( ctx.done );
733
734  rv = unlink( &dev[0] );
735  rtems_test_assert( rv == 0 );
736
737  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
738}
739
740static bool set_attributes_error(
741  rtems_termios_device_context *base,
742  const struct termios *term
743)
744{
745  device_context *ctx = (device_context *) base;
746
747  (void) term;
748
749  ctx->done = true;
750
751  return false;
752}
753
754static void test_set_attributes_error(void)
755{
756  static const rtems_termios_device_handler handler = {
757    .set_attributes = set_attributes_error
758  };
759  static const char dev[] = "/foobar";
760
761  rtems_resource_snapshot snapshot;
762  rtems_status_code sc;
763  struct termios term;
764  device_context ctx = {
765    .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "abc" ),
766    .done = false
767  };
768  int fd;
769  int rv;
770
771  rtems_resource_snapshot_take( &snapshot );
772
773  sc = rtems_termios_device_install( &dev[0], &handler, NULL, &ctx.base );
774  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
775
776  fd = open( &dev[0], O_RDWR );
777  rtems_test_assert( fd >= 0 );
778
779  rtems_test_assert( !ctx.done );
780  errno = 0;
781  rv = ioctl( fd, TIOCSETA, &term );
782  rtems_test_assert( rv == -1 );
783  rtems_test_assert( errno == EIO );
784  rtems_test_assert( ctx.done );
785
786  rv = close( fd );
787  rtems_test_assert( rv == 0 );
788
789  rv = unlink( &dev[0] );
790  rtems_test_assert( rv == 0 );
791
792  rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
793}
794
795static void test_set_best_baud(void)
796{
797  static const struct {
798    uint32_t baud;
799    speed_t speed;
800  } baud_to_speed_table[] = {
801    { 0,          B0 },
802    { 25,         B0 },
803    { 26,         B50 },
804    { 50,         B50 },
805    { 62,         B50 },
806    { 63,         B75 },
807    { 75,         B75 },
808    { 110,        B110 },
809    { 134,        B134 },
810    { 150,        B150 },
811    { 200,        B200 },
812    { 300,        B300 },
813    { 600,        B600 },
814    { 1200,       B1200 },
815    { 1800,       B1800 },
816    { 2400,       B2400 },
817    { 4800,       B4800 },
818    { 9600,       B9600 },
819    { 19200,      B19200 },
820    { 38400,      B38400 },
821    { 57600,      B57600 },
822    { 115200,     B115200 },
823    { 230400,     B230400 },
824    { 460800,     B460800 },
825    { 0xffffffff, B460800 }
826  };
827
828  size_t n = RTEMS_ARRAY_SIZE(baud_to_speed_table);
829  size_t i;
830
831  for ( i = 0; i < n; ++i ) {
832    struct termios term;
833
834    memset( &term, 0xff, sizeof( term ) );
835    rtems_termios_set_best_baud( &term, baud_to_speed_table[ i ].baud );
836
837    rtems_test_assert( term.c_ispeed == baud_to_speed_table[ i ].speed );
838    rtems_test_assert( term.c_ospeed == baud_to_speed_table[ i ].speed );
839  }
840}
841
842static rtems_task Init(
843  rtems_task_argument ignored
844)
845{
846  int                       rc;
847  rtems_status_code         sc;
848  rtems_device_major_number registered;
849  int                       test;
850  struct termios            t;
851  int index = 0;
852
853  TEST_BEGIN();
854
855  test_termios_baud2index();
856  test_termios_baud2number();
857  test_termios_number_to_baud();
858
859  sc = rtems_termios_bufsize( 256, 128, 64 );
860  directive_failed( sc, "rtems_termios_bufsize" );
861
862  /*
863   * Register a driver
864   */
865  puts(
866    "\n"
867    "Init - rtems_io_register_driver - Termios Test Driver - OK"
868  );
869  sc = rtems_io_register_driver( 0, &test_driver, &registered );
870  printf( "Init - Major slot returned = %d\n", (int) registered );
871  directive_failed( sc, "rtems_io_register_driver" );
872
873  /*
874   * Test baud rate
875   */
876  puts( "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
877  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
878  if ( test == -1 ) {
879    printf( "ERROR - baud opening test device (%d)\n", test );
880    rtems_test_exit(0);
881  }
882
883  /*
884   * tcsetattr - ERROR invalid operation
885   */
886  puts( "tcsetattr - invalid operation - EINVAL" );
887  rc = tcsetattr( test, INT_MAX, &t );
888  rtems_test_assert( rc == -1 );
889  rtems_test_assert( errno == EINVAL );
890
891  test_termios_cfmakeraw();
892  test_termios_cfmakesane();
893
894  /*
895   * tcsetattr - TCSADRAIN
896   */
897  puts( "\ntcsetattr - drain - OK" );
898  rc = tcsetattr( test, TCSADRAIN, &t );
899  rtems_test_assert( rc == 0 );
900
901  test_termios_set_baud(test);
902
903  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
904  rc = close( test );
905  if ( rc != 0 ) {
906    printf( "ERROR - baud close test device (%d) %s\n", test, strerror(errno) );
907    rtems_test_exit(0);
908  }
909
910  /*
911   * Test character size
912   */
913  puts(
914    "\n"
915    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
916  );
917  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
918  if ( test == -1 ) {
919    printf( "ERROR - size open test device (%d) %s\n", test, strerror(errno) );
920    rtems_test_exit(0);
921  }
922
923  test_termios_set_charsize(test);
924
925  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
926  rc = close( test );
927  if ( rc != 0 ) {
928    printf( "ERROR - size close test device (%d) %s\n", test, strerror(errno) );
929    rtems_test_exit(0);
930  }
931
932  /*
933   * Test parity
934   */
935  puts(
936    "\n"
937    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
938  );
939  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
940  if ( test == -1 ) {
941    printf( "ERROR - parity open test device (%d) %s\n",
942      test, strerror(errno) );
943    rtems_test_exit(0);
944  }
945
946  test_termios_set_parity(test);
947
948  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
949  rc = close( test );
950  if ( rc != 0 ) {
951    printf( "ERROR - parity close test device (%d) %s\n",
952      test, strerror(errno) );
953    rtems_test_exit(0);
954  }
955
956  /*
957   * Test stop bits
958   */
959  puts(
960    "\n"
961    "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
962  );
963  test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
964  if ( test == -1 ) {
965    printf( "ERROR - stop bits open test device (%d) %s\n",
966      test, strerror(errno) );
967    rtems_test_exit(0);
968  }
969
970  test_termios_set_stop_bits(test);
971
972  test_termios_cfoutspeed();
973
974  test_termios_cfinspeed();
975
976  test_termios_cfsetspeed();
977
978  puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
979  rc = close( test );
980  if ( rc != 0 ) {
981    printf( "ERROR - stop bits close test device (%d) %s\n",
982      test, strerror(errno) );
983    rtems_test_exit(0);
984  }
985
986
987  puts( "Multiple open of the device" );
988  for( ; index < 26; ++index ) {
989    test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
990    rtems_test_assert( test != -1 );
991    rc = close( test );
992    rtems_test_assert( rc == 0 );
993  }
994  puts( "" );
995
996  test_device_install_remove();
997  test_first_open_error();
998  test_set_attributes_error();
999  test_set_best_baud();
1000
1001  TEST_END();
1002  rtems_test_exit(0);
1003}
1004
1005/* configuration information */
1006
1007#define CONFIGURE_APPLICATION_PREREQUISITE_DRIVERS \
1008  { .initialization_entry = test_early_device_install }
1009
1010#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
1011#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
1012
1013/* include an extra slot for registering the termios one dynamically */
1014#define CONFIGURE_MAXIMUM_DRIVERS 4
1015
1016/* one for the console and one for the test port */
1017#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 3
1018
1019/* we need to be able to open the test device */
1020#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
1021
1022#define CONFIGURE_MAXIMUM_TASKS         1
1023#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
1024
1025#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
1026
1027#define CONFIGURE_INIT
1028#include <rtems/confdefs.h>
1029
1030/* global variables */
Note: See TracBrowser for help on using the repository browser.