source: rtems/testsuites/libtests/termios01/init.c

Last change on this file was acceb47, checked in by Joel Sherrill <joel@…>, on 04/01/22 at 19:24:13

testsuites/libtests/[p-z]*: Change license to BSD-2

Updates #3053.

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