1use crate::backend::c;
2use crate::{backend, io};
3use bitflags::bitflags;
4
5#[repr(C)]
10#[derive(Clone)]
11pub struct Termios {
12 #[doc(alias = "c_iflag")]
14 pub input_modes: InputModes,
15
16 #[doc(alias = "c_oflag")]
18 pub output_modes: OutputModes,
19
20 #[doc(alias = "c_cflag")]
22 pub control_modes: ControlModes,
23
24 #[doc(alias = "c_lflag")]
26 pub local_modes: LocalModes,
27
28 #[doc(alias = "c_line")]
30 #[cfg(not(all(linux_raw, any(target_arch = "powerpc", target_arch = "powerpc64"))))]
31 #[cfg(any(
32 linux_like,
33 target_env = "newlib",
34 target_os = "fuchsia",
35 target_os = "haiku",
36 target_os = "redox"
37 ))]
38 pub line_discipline: c::cc_t,
39
40 #[doc(alias = "c_cc")]
42 #[cfg(not(target_os = "haiku"))]
43 pub special_codes: SpecialCodes,
44
45 #[cfg(target_os = "nto")]
46 pub(crate) __reserved: [c::c_uint; 3],
47
48 #[doc(alias = "c_line")]
51 #[cfg(all(linux_raw, any(target_arch = "powerpc", target_arch = "powerpc64")))]
52 pub line_discipline: c::cc_t,
53
54 #[cfg(not(any(solarish, all(libc, target_env = "newlib"), target_os = "aix")))]
59 pub(crate) input_speed: c::speed_t,
60
61 #[cfg(not(any(solarish, all(libc, target_env = "newlib"), target_os = "aix")))]
66 pub(crate) output_speed: c::speed_t,
67
68 #[doc(alias = "c_cc")]
70 #[cfg(target_os = "haiku")]
71 pub special_codes: SpecialCodes,
72}
73
74impl Termios {
75 #[cfg(not(target_os = "nto"))]
80 #[doc(alias = "cfmakeraw")]
81 #[inline]
82 pub fn make_raw(&mut self) {
83 backend::termios::syscalls::cfmakeraw(self)
84 }
85
86 #[doc(alias = "c_ispeed")]
92 #[doc(alias = "cfgetispeed")]
93 #[doc(alias = "cfgetspeed")]
94 #[inline]
95 pub fn input_speed(&self) -> u32 {
96 #[cfg(any(linux_kernel, bsd))]
98 {
99 debug_assert!(u32::try_from(self.input_speed).is_ok());
100 self.input_speed as u32
101 }
102
103 #[cfg(any(solarish, all(libc, target_env = "newlib"), target_os = "aix"))]
105 unsafe {
106 speed::decode(c::cfgetispeed(crate::utils::as_ptr(self).cast())).unwrap()
107 }
108
109 #[cfg(not(any(
111 linux_kernel,
112 bsd,
113 solarish,
114 all(libc, target_env = "newlib"),
115 target_os = "aix"
116 )))]
117 {
118 speed::decode(self.input_speed).unwrap()
119 }
120 }
121
122 #[inline]
128 pub fn output_speed(&self) -> u32 {
129 #[cfg(any(linux_kernel, bsd))]
131 {
132 debug_assert!(u32::try_from(self.output_speed).is_ok());
133 self.output_speed as u32
134 }
135
136 #[cfg(any(solarish, all(libc, target_env = "newlib"), target_os = "aix"))]
138 unsafe {
139 speed::decode(c::cfgetospeed(crate::utils::as_ptr(self).cast())).unwrap()
140 }
141
142 #[cfg(not(any(
144 linux_kernel,
145 bsd,
146 solarish,
147 all(libc, target_env = "newlib"),
148 target_os = "aix"
149 )))]
150 {
151 speed::decode(self.output_speed).unwrap()
152 }
153 }
154
155 #[cfg(not(target_os = "nto"))]
163 #[doc(alias = "cfsetspeed")]
164 #[doc(alias = "CBAUD")]
165 #[doc(alias = "CBAUDEX")]
166 #[doc(alias = "CIBAUD")]
167 #[doc(alias = "CIBAUDEX")]
168 #[inline]
169 pub fn set_speed(&mut self, new_speed: u32) -> io::Result<()> {
170 backend::termios::syscalls::set_speed(self, new_speed)
171 }
172
173 #[doc(alias = "c_ispeed")]
183 #[doc(alias = "cfsetispeed")]
184 #[doc(alias = "CIBAUD")]
185 #[doc(alias = "CIBAUDEX")]
186 #[inline]
187 pub fn set_input_speed(&mut self, new_speed: u32) -> io::Result<()> {
188 backend::termios::syscalls::set_input_speed(self, new_speed)
189 }
190
191 #[doc(alias = "c_ospeed")]
201 #[doc(alias = "cfsetospeed")]
202 #[doc(alias = "CBAUD")]
203 #[doc(alias = "CBAUDEX")]
204 #[inline]
205 pub fn set_output_speed(&mut self, new_speed: u32) -> io::Result<()> {
206 backend::termios::syscalls::set_output_speed(self, new_speed)
207 }
208}
209
210impl core::fmt::Debug for Termios {
211 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
212 let mut d = f.debug_struct("Termios");
213 d.field("input_modes", &self.input_modes);
214 d.field("output_modes", &self.output_modes);
215 d.field("control_modes", &self.control_modes);
216 d.field("local_modes", &self.local_modes);
217 #[cfg(any(
218 linux_like,
219 target_env = "newlib",
220 target_os = "fuchsia",
221 target_os = "haiku",
222 target_os = "redox"
223 ))]
224 {
225 d.field("line_discipline", &self.line_discipline);
226 }
227 d.field("special_codes", &self.special_codes);
228 d.field("input_speed", &self.input_speed());
229 d.field("output_speed", &self.output_speed());
230 d.finish()
231 }
232}
233
234bitflags! {
235 #[repr(transparent)]
237 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
238 pub struct InputModes: c::tcflag_t {
239 const IGNBRK = c::IGNBRK;
241
242 const BRKINT = c::BRKINT;
244
245 const IGNPAR = c::IGNPAR;
247
248 const PARMRK = c::PARMRK;
250
251 const INPCK = c::INPCK;
253
254 const ISTRIP = c::ISTRIP;
256
257 const INLCR = c::INLCR;
259
260 const IGNCR = c::IGNCR;
262
263 const ICRNL = c::ICRNL;
265
266 #[cfg(any(linux_kernel, solarish, target_os = "aix", target_os = "haiku", target_os = "nto"))]
268 const IUCLC = c::IUCLC;
269
270 const IXON = c::IXON;
272
273 #[cfg(not(target_os = "redox"))]
275 const IXANY = c::IXANY;
276
277 const IXOFF = c::IXOFF;
279
280 #[cfg(not(any(target_os = "haiku", target_os = "redox")))]
282 const IMAXBEL = c::IMAXBEL;
283
284 #[cfg(not(any(
286 freebsdlike,
287 netbsdlike,
288 solarish,
289 target_os = "aix",
290 target_os = "emscripten",
291 target_os = "haiku",
292 target_os = "hurd",
293 target_os = "redox",
294 )))]
295 const IUTF8 = c::IUTF8;
296
297 const _ = !0;
299 }
300}
301
302bitflags! {
303 #[repr(transparent)]
305 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
306 pub struct OutputModes: c::tcflag_t {
307 const OPOST = c::OPOST;
309
310 #[cfg(not(any(
312 apple,
313 freebsdlike,
314 target_os = "aix",
315 target_os = "netbsd",
316 target_os = "redox",
317 )))]
318 const OLCUC = c::OLCUC;
319
320 const ONLCR = c::ONLCR;
322
323 const OCRNL = c::OCRNL;
325
326 const ONOCR = c::ONOCR;
328
329 const ONLRET = c::ONLRET;
331
332 #[cfg(not(bsd))]
334 const OFILL = c::OFILL;
335
336 #[cfg(not(bsd))]
338 const OFDEL = c::OFDEL;
339
340 #[cfg(not(any(bsd, solarish, target_os = "redox")))]
342 const NLDLY = c::NLDLY;
343
344 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
346 const NL0 = c::NL0;
347
348 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
350 const NL1 = c::NL1;
351
352 #[cfg(not(any(bsd, solarish, target_os = "redox")))]
354 const CRDLY = c::CRDLY;
355
356 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
358 const CR0 = c::CR0;
359
360 #[cfg(not(any(
362 target_env = "musl",
363 bsd,
364 solarish,
365 target_os = "emscripten",
366 target_os = "fuchsia",
367 target_os = "redox",
368 )))]
369 const CR1 = c::CR1;
370
371 #[cfg(not(any(
373 target_env = "musl",
374 bsd,
375 solarish,
376 target_os = "emscripten",
377 target_os = "fuchsia",
378 target_os = "redox",
379 )))]
380 const CR2 = c::CR2;
381
382 #[cfg(not(any(
384 target_env = "musl",
385 bsd,
386 solarish,
387 target_os = "emscripten",
388 target_os = "fuchsia",
389 target_os = "redox",
390 )))]
391 const CR3 = c::CR3;
392
393 #[cfg(not(any(
395 netbsdlike,
396 solarish,
397 target_os = "dragonfly",
398 target_os = "redox",
399 )))]
400 const TABDLY = c::TABDLY;
401
402 #[cfg(not(any(
404 netbsdlike,
405 solarish,
406 target_os = "dragonfly",
407 target_os = "fuchsia",
408 target_os = "redox",
409 )))]
410 const TAB0 = c::TAB0;
411
412 #[cfg(not(any(
414 target_env = "musl",
415 bsd,
416 solarish,
417 target_os = "emscripten",
418 target_os = "fuchsia",
419 target_os = "redox",
420 )))]
421 const TAB1 = c::TAB1;
422
423 #[cfg(not(any(
425 target_env = "musl",
426 bsd,
427 solarish,
428 target_os = "emscripten",
429 target_os = "fuchsia",
430 target_os = "redox",
431 )))]
432 const TAB2 = c::TAB2;
433
434 #[cfg(not(any(
436 target_env = "musl",
437 bsd,
438 solarish,
439 target_os = "emscripten",
440 target_os = "fuchsia",
441 target_os = "redox",
442 )))]
443 const TAB3 = c::TAB3;
444
445 #[cfg(not(any(
447 bsd,
448 solarish,
449 target_os = "aix",
450 target_os = "haiku",
451 target_os = "redox",
452 )))]
453 const XTABS = c::XTABS;
454
455 #[cfg(not(any(bsd, solarish, target_os = "redox")))]
457 const BSDLY = c::BSDLY;
458
459 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
461 const BS0 = c::BS0;
462
463 #[cfg(not(any(
465 target_env = "musl",
466 bsd,
467 solarish,
468 target_os = "emscripten",
469 target_os = "fuchsia",
470 target_os = "redox",
471 )))]
472 const BS1 = c::BS1;
473
474 #[cfg(not(any(bsd, solarish, target_os = "redox")))]
476 const FFDLY = c::FFDLY;
477
478 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
480 const FF0 = c::FF0;
481
482 #[cfg(not(any(
484 target_env = "musl",
485 bsd,
486 solarish,
487 target_os = "emscripten",
488 target_os = "fuchsia",
489 target_os = "redox",
490 )))]
491 const FF1 = c::FF1;
492
493 #[cfg(not(any(bsd, solarish, target_os = "redox")))]
495 const VTDLY = c::VTDLY;
496
497 #[cfg(not(any(bsd, solarish, target_os = "fuchsia", target_os = "redox")))]
499 const VT0 = c::VT0;
500
501 #[cfg(not(any(
503 target_env = "musl",
504 bsd,
505 solarish,
506 target_os = "emscripten",
507 target_os = "fuchsia",
508 target_os = "redox",
509 )))]
510 const VT1 = c::VT1;
511
512 const _ = !0;
514 }
515}
516
517bitflags! {
518 #[repr(transparent)]
524 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
525 pub struct ControlModes: c::tcflag_t {
526 const CSIZE = c::CSIZE;
528
529 const CS5 = c::CS5;
531
532 const CS6 = c::CS6;
534
535 const CS7 = c::CS7;
537
538 const CS8 = c::CS8;
540
541 const CSTOPB = c::CSTOPB;
543
544 const CREAD = c::CREAD;
546
547 const PARENB = c::PARENB;
549
550 const PARODD = c::PARODD;
552
553 const HUPCL = c::HUPCL;
555
556 const CLOCAL = c::CLOCAL;
558
559 #[cfg(not(any(target_os = "aix", target_os = "nto", target_os = "redox")))]
561 const CRTSCTS = c::CRTSCTS;
562
563 #[cfg(not(any(
565 bsd,
566 solarish,
567 target_os = "aix",
568 target_os = "emscripten",
569 target_os = "haiku",
570 target_os = "hurd",
571 target_os = "nto",
572 target_os = "redox",
573 )))]
574 const CMSPAR = c::CMSPAR;
575
576 const _ = !0;
578 }
579}
580
581bitflags! {
582 #[repr(transparent)]
584 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
585 pub struct LocalModes: c::tcflag_t {
586 #[cfg(any(linux_kernel, target_arch = "s390x", target_os = "haiku"))]
588 const XCASE = c::XCASE;
589
590 #[cfg(not(target_os = "redox"))]
592 const ECHOCTL = c::ECHOCTL;
593
594 #[cfg(not(any(target_os = "nto", target_os = "redox")))]
596 const ECHOPRT = c::ECHOPRT;
597
598 #[cfg(not(target_os = "redox"))]
600 const ECHOKE = c::ECHOKE;
601
602 #[cfg(not(any(target_os = "nto", target_os = "redox")))]
604 const FLUSHO = c::FLUSHO;
605
606 #[cfg(not(any(target_os = "nto", target_os = "redox")))]
608 const PENDIN = c::PENDIN;
609
610 #[cfg(not(any(target_os = "aix", target_os = "haiku", target_os = "nto", target_os = "redox")))]
612 const EXTPROC = c::EXTPROC;
613
614 const ISIG = c::ISIG;
616
617 const ICANON = c::ICANON;
620
621 const ECHO = c::ECHO;
623
624 const ECHOE = c::ECHOE;
626
627 const ECHOK = c::ECHOK;
629
630 const ECHONL = c::ECHONL;
632
633 const NOFLSH = c::NOFLSH;
635
636 const TOSTOP = c::TOSTOP;
638
639 const IEXTEN = c::IEXTEN;
641
642 const _ = !0;
644 }
645}
646
647pub mod speed {
656 #[cfg(not(bsd))]
657 use crate::backend::c;
658
659 pub const B0: u32 = 0;
661
662 pub const B50: u32 = 50;
664
665 pub const B75: u32 = 75;
667
668 pub const B110: u32 = 110;
670
671 pub const B134: u32 = 134;
673
674 pub const B150: u32 = 150;
676
677 pub const B200: u32 = 200;
679
680 pub const B300: u32 = 300;
682
683 pub const B600: u32 = 600;
685
686 pub const B1200: u32 = 1200;
688
689 pub const B1800: u32 = 1800;
691
692 pub const B2400: u32 = 2400;
694
695 pub const B4800: u32 = 4800;
697
698 pub const B9600: u32 = 9600;
700
701 #[doc(alias = "EXTA")]
703 pub const B19200: u32 = 19200;
704
705 #[doc(alias = "EXTB")]
707 pub const B38400: u32 = 38400;
708
709 #[cfg(not(target_os = "aix"))]
711 pub const B57600: u32 = 57600;
712
713 #[cfg(not(target_os = "aix"))]
715 pub const B115200: u32 = 115_200;
716
717 #[cfg(not(target_os = "aix"))]
719 pub const B230400: u32 = 230_400;
720
721 #[cfg(not(any(
723 apple,
724 target_os = "aix",
725 target_os = "dragonfly",
726 target_os = "haiku",
727 target_os = "openbsd"
728 )))]
729 pub const B460800: u32 = 460_800;
730
731 #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))]
733 pub const B500000: u32 = 500_000;
734
735 #[cfg(not(any(bsd, solarish, target_os = "aix", target_os = "haiku")))]
737 pub const B576000: u32 = 576_000;
738
739 #[cfg(not(any(
741 apple,
742 target_os = "aix",
743 target_os = "dragonfly",
744 target_os = "haiku",
745 target_os = "openbsd"
746 )))]
747 pub const B921600: u32 = 921_600;
748
749 #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))]
751 pub const B1000000: u32 = 1_000_000;
752
753 #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))]
755 pub const B1152000: u32 = 1_152_000;
756
757 #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))]
759 pub const B1500000: u32 = 1_500_000;
760
761 #[cfg(not(any(bsd, target_os = "aix", target_os = "haiku", target_os = "solaris")))]
763 pub const B2000000: u32 = 2_000_000;
764
765 #[cfg(not(any(
767 target_arch = "sparc",
768 target_arch = "sparc64",
769 bsd,
770 target_os = "aix",
771 target_os = "haiku",
772 target_os = "solaris",
773 )))]
774 pub const B2500000: u32 = 2_500_000;
775
776 #[cfg(not(any(
778 target_arch = "sparc",
779 target_arch = "sparc64",
780 bsd,
781 target_os = "aix",
782 target_os = "haiku",
783 target_os = "solaris",
784 )))]
785 pub const B3000000: u32 = 3_000_000;
786
787 #[cfg(not(any(
789 target_arch = "sparc",
790 target_arch = "sparc64",
791 bsd,
792 target_os = "aix",
793 target_os = "haiku",
794 target_os = "solaris",
795 )))]
796 pub const B3500000: u32 = 3_500_000;
797
798 #[cfg(not(any(
800 target_arch = "sparc",
801 target_arch = "sparc64",
802 bsd,
803 target_os = "aix",
804 target_os = "haiku",
805 target_os = "solaris",
806 )))]
807 pub const B4000000: u32 = 4_000_000;
808
809 #[cfg(not(any(
822 bsd,
823 all(linux_kernel, any(target_arch = "powerpc", target_arch = "powerpc64"))
824 )))]
825 pub(crate) const fn decode(encoded_speed: c::speed_t) -> Option<u32> {
826 match encoded_speed {
827 c::B0 => Some(0),
828 c::B50 => Some(50),
829 c::B75 => Some(75),
830 c::B110 => Some(110),
831 c::B134 => Some(134),
832 c::B150 => Some(150),
833 c::B200 => Some(200),
834 c::B300 => Some(300),
835 c::B600 => Some(600),
836 c::B1200 => Some(1200),
837 c::B1800 => Some(1800),
838 c::B2400 => Some(2400),
839 c::B4800 => Some(4800),
840 c::B9600 => Some(9600),
841 c::B19200 => Some(19200),
842 c::B38400 => Some(38400),
843 #[cfg(not(target_os = "aix"))]
844 c::B57600 => Some(57600),
845 #[cfg(not(target_os = "aix"))]
846 c::B115200 => Some(115_200),
847 #[cfg(not(any(target_os = "aix", target_os = "nto")))]
848 c::B230400 => Some(230_400),
849 #[cfg(not(any(
850 apple,
851 target_os = "aix",
852 target_os = "dragonfly",
853 target_os = "haiku",
854 target_os = "nto",
855 target_os = "openbsd"
856 )))]
857 c::B460800 => Some(460_800),
858 #[cfg(not(any(
859 bsd,
860 solarish,
861 target_os = "aix",
862 target_os = "haiku",
863 target_os = "nto"
864 )))]
865 c::B500000 => Some(500_000),
866 #[cfg(not(any(
867 bsd,
868 solarish,
869 target_os = "aix",
870 target_os = "haiku",
871 target_os = "nto"
872 )))]
873 c::B576000 => Some(576_000),
874 #[cfg(not(any(
875 apple,
876 target_os = "aix",
877 target_os = "dragonfly",
878 target_os = "haiku",
879 target_os = "nto",
880 target_os = "openbsd"
881 )))]
882 c::B921600 => Some(921_600),
883 #[cfg(not(any(
884 bsd,
885 target_os = "aix",
886 target_os = "haiku",
887 target_os = "nto",
888 target_os = "solaris"
889 )))]
890 c::B1000000 => Some(1_000_000),
891 #[cfg(not(any(
892 bsd,
893 target_os = "aix",
894 target_os = "haiku",
895 target_os = "nto",
896 target_os = "solaris"
897 )))]
898 c::B1152000 => Some(1_152_000),
899 #[cfg(not(any(
900 bsd,
901 target_os = "aix",
902 target_os = "haiku",
903 target_os = "nto",
904 target_os = "solaris"
905 )))]
906 c::B1500000 => Some(1_500_000),
907 #[cfg(not(any(
908 bsd,
909 target_os = "aix",
910 target_os = "haiku",
911 target_os = "nto",
912 target_os = "solaris"
913 )))]
914 c::B2000000 => Some(2_000_000),
915 #[cfg(not(any(
916 target_arch = "sparc",
917 target_arch = "sparc64",
918 bsd,
919 target_os = "aix",
920 target_os = "haiku",
921 target_os = "nto",
922 target_os = "solaris",
923 )))]
924 c::B2500000 => Some(2_500_000),
925 #[cfg(not(any(
926 target_arch = "sparc",
927 target_arch = "sparc64",
928 bsd,
929 target_os = "aix",
930 target_os = "haiku",
931 target_os = "nto",
932 target_os = "solaris",
933 )))]
934 c::B3000000 => Some(3_000_000),
935 #[cfg(not(any(
936 target_arch = "sparc",
937 target_arch = "sparc64",
938 bsd,
939 target_os = "aix",
940 target_os = "haiku",
941 target_os = "nto",
942 target_os = "solaris",
943 )))]
944 c::B3500000 => Some(3_500_000),
945 #[cfg(not(any(
946 target_arch = "sparc",
947 target_arch = "sparc64",
948 bsd,
949 target_os = "aix",
950 target_os = "haiku",
951 target_os = "nto",
952 target_os = "solaris",
953 )))]
954 c::B4000000 => Some(4_000_000),
955 _ => None,
956 }
957 }
958
959 #[cfg(not(bsd))]
962 pub(crate) const fn encode(speed: u32) -> Option<c::speed_t> {
963 match speed {
964 0 => Some(c::B0),
965 50 => Some(c::B50),
966 75 => Some(c::B75),
967 110 => Some(c::B110),
968 134 => Some(c::B134),
969 150 => Some(c::B150),
970 200 => Some(c::B200),
971 300 => Some(c::B300),
972 600 => Some(c::B600),
973 1200 => Some(c::B1200),
974 1800 => Some(c::B1800),
975 2400 => Some(c::B2400),
976 4800 => Some(c::B4800),
977 9600 => Some(c::B9600),
978 19200 => Some(c::B19200),
979 38400 => Some(c::B38400),
980 #[cfg(not(target_os = "aix"))]
981 57600 => Some(c::B57600),
982 #[cfg(not(target_os = "aix"))]
983 115_200 => Some(c::B115200),
984 #[cfg(not(any(target_os = "aix", target_os = "nto")))]
985 230_400 => Some(c::B230400),
986 #[cfg(not(any(
987 apple,
988 target_os = "aix",
989 target_os = "dragonfly",
990 target_os = "haiku",
991 target_os = "nto",
992 target_os = "openbsd",
993 )))]
994 460_800 => Some(c::B460800),
995 #[cfg(not(any(
996 bsd,
997 solarish,
998 target_os = "aix",
999 target_os = "haiku",
1000 target_os = "nto"
1001 )))]
1002 500_000 => Some(c::B500000),
1003 #[cfg(not(any(
1004 bsd,
1005 solarish,
1006 target_os = "aix",
1007 target_os = "haiku",
1008 target_os = "nto"
1009 )))]
1010 576_000 => Some(c::B576000),
1011 #[cfg(not(any(
1012 apple,
1013 target_os = "aix",
1014 target_os = "dragonfly",
1015 target_os = "haiku",
1016 target_os = "nto",
1017 target_os = "openbsd"
1018 )))]
1019 921_600 => Some(c::B921600),
1020 #[cfg(not(any(
1021 bsd,
1022 target_os = "aix",
1023 target_os = "haiku",
1024 target_os = "nto",
1025 target_os = "solaris"
1026 )))]
1027 1_000_000 => Some(c::B1000000),
1028 #[cfg(not(any(
1029 bsd,
1030 target_os = "aix",
1031 target_os = "haiku",
1032 target_os = "nto",
1033 target_os = "solaris"
1034 )))]
1035 1_152_000 => Some(c::B1152000),
1036 #[cfg(not(any(
1037 bsd,
1038 target_os = "aix",
1039 target_os = "haiku",
1040 target_os = "nto",
1041 target_os = "solaris"
1042 )))]
1043 1_500_000 => Some(c::B1500000),
1044 #[cfg(not(any(
1045 bsd,
1046 target_os = "aix",
1047 target_os = "haiku",
1048 target_os = "nto",
1049 target_os = "solaris"
1050 )))]
1051 2_000_000 => Some(c::B2000000),
1052 #[cfg(not(any(
1053 target_arch = "sparc",
1054 target_arch = "sparc64",
1055 bsd,
1056 target_os = "aix",
1057 target_os = "haiku",
1058 target_os = "nto",
1059 target_os = "solaris",
1060 )))]
1061 2_500_000 => Some(c::B2500000),
1062 #[cfg(not(any(
1063 target_arch = "sparc",
1064 target_arch = "sparc64",
1065 bsd,
1066 target_os = "aix",
1067 target_os = "haiku",
1068 target_os = "nto",
1069 target_os = "solaris",
1070 )))]
1071 3_000_000 => Some(c::B3000000),
1072 #[cfg(not(any(
1073 target_arch = "sparc",
1074 target_arch = "sparc64",
1075 bsd,
1076 target_os = "aix",
1077 target_os = "haiku",
1078 target_os = "nto",
1079 target_os = "solaris",
1080 )))]
1081 3_500_000 => Some(c::B3500000),
1082 #[cfg(not(any(
1083 target_arch = "sparc",
1084 target_arch = "sparc64",
1085 bsd,
1086 target_os = "aix",
1087 target_os = "haiku",
1088 target_os = "nto",
1089 target_os = "solaris",
1090 )))]
1091 4_000_000 => Some(c::B4000000),
1092 _ => None,
1093 }
1094 }
1095}
1096
1097#[repr(transparent)]
1100#[derive(Clone, Debug)]
1101pub struct SpecialCodes(pub(crate) [c::cc_t; c::NCCS as usize]);
1102
1103impl core::ops::Index<SpecialCodeIndex> for SpecialCodes {
1104 type Output = c::cc_t;
1105
1106 fn index(&self, index: SpecialCodeIndex) -> &Self::Output {
1107 &self.0[index.0]
1108 }
1109}
1110
1111impl core::ops::IndexMut<SpecialCodeIndex> for SpecialCodes {
1112 fn index_mut(&mut self, index: SpecialCodeIndex) -> &mut Self::Output {
1113 &mut self.0[index.0]
1114 }
1115}
1116
1117#[derive(Copy, Clone, Eq, PartialEq, Hash)]
1119pub struct SpecialCodeIndex(usize);
1120
1121#[rustfmt::skip]
1122impl SpecialCodeIndex {
1123 pub const VINTR: Self = Self(c::VINTR as usize);
1125
1126 pub const VQUIT: Self = Self(c::VQUIT as usize);
1128
1129 pub const VERASE: Self = Self(c::VERASE as usize);
1131
1132 pub const VKILL: Self = Self(c::VKILL as usize);
1134
1135 pub const VEOF: Self = Self(c::VEOF as usize);
1137
1138 pub const VTIME: Self = Self(c::VTIME as usize);
1140
1141 pub const VMIN: Self = Self(c::VMIN as usize);
1143
1144 #[cfg(not(any(
1146 bsd,
1147 solarish,
1148 target_os = "aix",
1149 target_os = "haiku",
1150 target_os = "hurd",
1151 target_os = "nto",
1152 )))]
1153 pub const VSWTC: Self = Self(c::VSWTC as usize);
1154
1155 pub const VSTART: Self = Self(c::VSTART as usize);
1157
1158 pub const VSTOP: Self = Self(c::VSTOP as usize);
1160
1161 pub const VSUSP: Self = Self(c::VSUSP as usize);
1163
1164 pub const VEOL: Self = Self(c::VEOL as usize);
1166
1167 #[cfg(not(target_os = "haiku"))]
1169 pub const VREPRINT: Self = Self(c::VREPRINT as usize);
1170
1171 #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
1173 pub const VDISCARD: Self = Self(c::VDISCARD as usize);
1174
1175 #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
1177 pub const VWERASE: Self = Self(c::VWERASE as usize);
1178
1179 #[cfg(not(target_os = "haiku"))]
1181 pub const VLNEXT: Self = Self(c::VLNEXT as usize);
1182
1183 pub const VEOL2: Self = Self(c::VEOL2 as usize);
1185
1186 #[cfg(any(solarish, target_os = "haiku", target_os = "nto"))]
1188 pub const VSWTCH: Self = Self(c::VSWTCH as usize);
1189
1190 #[cfg(any(bsd, solarish, target_os = "aix", target_os = "hurd", target_os = "nto"))]
1192 pub const VDSUSP: Self = Self(c::VDSUSP as usize);
1193
1194 #[cfg(any(bsd, target_os = "hurd", target_os = "illumos"))]
1196 pub const VSTATUS: Self = Self(c::VSTATUS as usize);
1197
1198 #[cfg(any(freebsdlike, target_os = "illumos"))]
1200 pub const VERASE2: Self = Self(c::VERASE2 as usize);
1201}
1202
1203impl core::fmt::Debug for SpecialCodeIndex {
1204 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1205 match *self {
1206 Self::VINTR => write!(f, "VINTR"),
1207 Self::VQUIT => write!(f, "VQUIT"),
1208 Self::VERASE => write!(f, "VERASE"),
1209 Self::VKILL => write!(f, "VKILL"),
1210 #[cfg(not(any(
1211 solarish,
1212 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1213 )))]
1214 Self::VEOF => write!(f, "VEOF"),
1215 #[cfg(not(any(
1216 solarish,
1217 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1218 )))]
1219 Self::VTIME => write!(f, "VTIME"),
1220 #[cfg(not(any(
1221 solarish,
1222 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1223 )))]
1224 Self::VMIN => write!(f, "VMIN"),
1225
1226 #[cfg(any(
1229 solarish,
1230 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1231 ))]
1232 Self::VMIN => write!(f, "VMIN/VEOF"),
1233 #[cfg(any(
1234 solarish,
1235 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1236 ))]
1237 Self::VTIME => write!(f, "VTIME/VEOL"),
1238
1239 #[cfg(not(any(
1240 bsd,
1241 solarish,
1242 target_os = "aix",
1243 target_os = "haiku",
1244 target_os = "hurd",
1245 target_os = "nto",
1246 )))]
1247 Self::VSWTC => write!(f, "VSWTC"),
1248 Self::VSTART => write!(f, "VSTART"),
1249 Self::VSTOP => write!(f, "VSTOP"),
1250 Self::VSUSP => write!(f, "VSUSP"),
1251 #[cfg(not(any(
1252 solarish,
1253 all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64"))
1254 )))]
1255 Self::VEOL => write!(f, "VEOL"),
1256 #[cfg(not(target_os = "haiku"))]
1257 Self::VREPRINT => write!(f, "VREPRINT"),
1258 #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
1259 Self::VDISCARD => write!(f, "VDISCARD"),
1260 #[cfg(not(any(target_os = "aix", target_os = "haiku")))]
1261 Self::VWERASE => write!(f, "VWERASE"),
1262 #[cfg(not(target_os = "haiku"))]
1263 Self::VLNEXT => write!(f, "VLNEXT"),
1264 Self::VEOL2 => write!(f, "VEOL2"),
1265 #[cfg(any(solarish, target_os = "haiku", target_os = "nto"))]
1266 Self::VSWTCH => write!(f, "VSWTCH"),
1267 #[cfg(any(
1268 bsd,
1269 solarish,
1270 target_os = "aix",
1271 target_os = "hurd",
1272 target_os = "nto"
1273 ))]
1274 Self::VDSUSP => write!(f, "VDSUSP"),
1275 #[cfg(any(bsd, target_os = "hurd", target_os = "illumos"))]
1276 Self::VSTATUS => write!(f, "VSTATUS"),
1277 #[cfg(any(freebsdlike, target_os = "illumos"))]
1278 Self::VERASE2 => write!(f, "VERASE2"),
1279
1280 _ => write!(f, "unknown"),
1281 }
1282 }
1283}
1284
1285#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1289#[repr(u32)]
1290pub enum OptionalActions {
1291 #[doc(alias = "TCSANOW")]
1293 Now = c::TCSANOW as u32,
1294
1295 #[doc(alias = "TCSADRAIN")]
1297 Drain = c::TCSADRAIN as u32,
1298
1299 #[doc(alias = "TCSAFLUSH")]
1302 Flush = c::TCSAFLUSH as u32,
1303}
1304
1305#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1309#[repr(u32)]
1310pub enum QueueSelector {
1311 #[doc(alias = "TCIFLUSH")]
1313 IFlush = c::TCIFLUSH as u32,
1314
1315 #[doc(alias = "TCOFLUSH")]
1317 OFlush = c::TCOFLUSH as u32,
1318
1319 #[doc(alias = "TCIOFLUSH")]
1321 IOFlush = c::TCIOFLUSH as u32,
1322}
1323
1324#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
1328#[repr(u32)]
1329pub enum Action {
1330 #[doc(alias = "TCOOFF")]
1332 OOff = c::TCOOFF as u32,
1333
1334 #[doc(alias = "TCOON")]
1336 OOn = c::TCOON as u32,
1337
1338 #[doc(alias = "TCIOFF")]
1340 IOff = c::TCIOFF as u32,
1341
1342 #[doc(alias = "TCION")]
1344 IOn = c::TCION as u32,
1345}
1346
1347#[doc(alias = "winsize")]
1351pub type Winsize = c::winsize;
1352
1353#[test]
1354fn termios_layouts() {
1355 check_renamed_type!(InputModes, tcflag_t);
1356 check_renamed_type!(OutputModes, tcflag_t);
1357 check_renamed_type!(ControlModes, tcflag_t);
1358 check_renamed_type!(LocalModes, tcflag_t);
1359
1360 #[cfg(linux_raw)]
1362 {
1363 check_renamed_type!(Termios, termios2);
1364 check_renamed_struct_renamed_field!(Termios, termios2, input_modes, c_iflag);
1365 check_renamed_struct_renamed_field!(Termios, termios2, output_modes, c_oflag);
1366 check_renamed_struct_renamed_field!(Termios, termios2, control_modes, c_cflag);
1367 check_renamed_struct_renamed_field!(Termios, termios2, local_modes, c_lflag);
1368 check_renamed_struct_renamed_field!(Termios, termios2, line_discipline, c_line);
1369 check_renamed_struct_renamed_field!(Termios, termios2, special_codes, c_cc);
1370 check_renamed_struct_renamed_field!(Termios, termios2, input_speed, c_ispeed);
1371 check_renamed_struct_renamed_field!(Termios, termios2, output_speed, c_ospeed);
1372
1373 check_renamed_struct_renamed_field!(Termios, termios, input_modes, c_iflag);
1376 check_renamed_struct_renamed_field!(Termios, termios, output_modes, c_oflag);
1377 check_renamed_struct_renamed_field!(Termios, termios, control_modes, c_cflag);
1378 check_renamed_struct_renamed_field!(Termios, termios, local_modes, c_lflag);
1379 check_renamed_struct_renamed_field!(Termios, termios, special_codes, c_cc);
1380
1381 #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
1384 const_assert_eq!(
1385 memoffset::offset_of!(Termios, input_speed),
1386 core::mem::size_of::<c::termios>()
1387 );
1388
1389 #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
1391 assert_eq_size!(c::termios2, c::termios);
1392 }
1393
1394 #[cfg(not(linux_raw))]
1395 {
1396 #[cfg(all(
1399 not(all(
1400 target_env = "gnu",
1401 any(
1402 target_arch = "mips",
1403 target_arch = "mips32r6",
1404 target_arch = "mips64",
1405 target_arch = "mips64r6",
1406 target_arch = "sparc",
1407 target_arch = "sparc64"
1408 )
1409 )),
1410 not(all(libc, target_os = "android"))
1411 ))]
1412 check_renamed_type!(Termios, termios);
1413 #[cfg(not(all(
1414 not(all(
1415 target_env = "gnu",
1416 any(
1417 target_arch = "mips",
1418 target_arch = "mips32r6",
1419 target_arch = "mips64",
1420 target_arch = "mips64r6",
1421 target_arch = "sparc",
1422 target_arch = "sparc64"
1423 )
1424 )),
1425 not(all(libc, target_os = "android"))
1426 )))]
1427 const_assert!(core::mem::size_of::<Termios>() >= core::mem::size_of::<c::termios>());
1428
1429 check_renamed_struct_renamed_field!(Termios, termios, input_modes, c_iflag);
1430 check_renamed_struct_renamed_field!(Termios, termios, output_modes, c_oflag);
1431 check_renamed_struct_renamed_field!(Termios, termios, control_modes, c_cflag);
1432 check_renamed_struct_renamed_field!(Termios, termios, local_modes, c_lflag);
1433 #[cfg(any(
1434 linux_like,
1435 target_env = "newlib",
1436 target_os = "fuchsia",
1437 target_os = "haiku",
1438 target_os = "redox"
1439 ))]
1440 check_renamed_struct_renamed_field!(Termios, termios, line_discipline, c_line);
1441 check_renamed_struct_renamed_field!(Termios, termios, special_codes, c_cc);
1442 #[cfg(not(any(
1443 linux_kernel,
1444 solarish,
1445 target_os = "emscripten",
1446 target_os = "fuchsia"
1447 )))]
1448 {
1449 check_renamed_struct_renamed_field!(Termios, termios, input_speed, c_ispeed);
1450 check_renamed_struct_renamed_field!(Termios, termios, output_speed, c_ospeed);
1451 }
1452 #[cfg(any(target_env = "musl", target_os = "fuchsia"))]
1453 {
1454 check_renamed_struct_renamed_field!(Termios, termios, input_speed, __c_ispeed);
1455 check_renamed_struct_renamed_field!(Termios, termios, output_speed, __c_ospeed);
1456 }
1457 }
1458
1459 check_renamed_type!(OptionalActions, c_int);
1460 check_renamed_type!(QueueSelector, c_int);
1461 check_renamed_type!(Action, c_int);
1462}
1463
1464#[test]
1465#[cfg(not(any(
1466 solarish,
1467 target_os = "emscripten",
1468 target_os = "haiku",
1469 target_os = "redox"
1470)))]
1471fn termios_legacy() {
1472 const_assert_eq!(c::EXTA, c::B19200);
1474 const_assert_eq!(c::EXTB, c::B38400);
1475}
1476
1477#[cfg(bsd)]
1478#[test]
1479fn termios_bsd() {
1480 const_assert_eq!(c::B0, 0);
1483 const_assert_eq!(c::B50, 50);
1484 const_assert_eq!(c::B19200, 19200);
1485 const_assert_eq!(c::B38400, 38400);
1486}
1487
1488#[test]
1489#[cfg(not(bsd))]
1490fn termios_speed_encoding() {
1491 assert_eq!(speed::encode(0), Some(c::B0));
1492 assert_eq!(speed::encode(50), Some(c::B50));
1493 assert_eq!(speed::encode(19200), Some(c::B19200));
1494 assert_eq!(speed::encode(38400), Some(c::B38400));
1495 assert_eq!(speed::encode(1), None);
1496 assert_eq!(speed::encode(!0), None);
1497
1498 #[cfg(not(linux_kernel))]
1499 {
1500 assert_eq!(speed::decode(c::B0), Some(0));
1501 assert_eq!(speed::decode(c::B50), Some(50));
1502 assert_eq!(speed::decode(c::B19200), Some(19200));
1503 assert_eq!(speed::decode(c::B38400), Some(38400));
1504 }
1505}
1506
1507#[cfg(linux_kernel)]
1508#[test]
1509fn termios_ioctl_contiguity() {
1510 const_assert_eq!(c::TCSETS2, c::TCSETS2 + 0);
1514 const_assert_eq!(c::TCSETSW2, c::TCSETS2 + 1);
1515 const_assert_eq!(c::TCSETSF2, c::TCSETS2 + 2);
1516
1517 const_assert_eq!(c::TCSANOW - c::TCSANOW, 0);
1518 const_assert_eq!(c::TCSADRAIN - c::TCSANOW, 1);
1519 const_assert_eq!(c::TCSAFLUSH - c::TCSANOW, 2);
1520
1521 #[cfg(any(
1523 target_arch = "mips",
1524 target_arch = "mips32r6",
1525 target_arch = "mips64",
1526 target_arch = "mips64r6"
1527 ))]
1528 {
1529 assert_eq!(i128::from(c::TCSANOW) - i128::from(c::TCSETS), 0);
1530 assert_eq!(i128::from(c::TCSADRAIN) - i128::from(c::TCSETS), 1);
1531 assert_eq!(i128::from(c::TCSAFLUSH) - i128::from(c::TCSETS), 2);
1532 }
1533 #[cfg(not(any(
1534 target_arch = "mips",
1535 target_arch = "mips32r6",
1536 target_arch = "mips64",
1537 target_arch = "mips64r6"
1538 )))]
1539 {
1540 const_assert_eq!(c::TCSANOW, 0);
1541 const_assert_eq!(c::TCSADRAIN, 1);
1542 const_assert_eq!(c::TCSAFLUSH, 2);
1543 }
1544}
1545
1546#[cfg(linux_kernel)]
1547#[test]
1548fn termios_cibaud() {
1549 const_assert_eq!(c::CIBAUD, c::CBAUD << c::IBSHIFT);
1551}