1//! A command which prints out information about the standard input,
2//! output, and error streams provided to it.
3
4#![cfg_attr(io_lifetimes_use_std, feature(io_safety))]
5
6#[cfg(not(windows))]
7use rustix::fd::AsFd;
8#[cfg(not(windows))]
9use rustix::io::{self, stderr, stdin, stdout};
10#[cfg(feature = "termios")]
11#[cfg(not(windows))]
12use rustix::termios::isatty;
13#[cfg(all(
14    not(any(windows, target_os = "fuchsia")),
15    feature = "termios",
16    feature = "procfs"
17))]
18use rustix::termios::ttyname;
19
20#[cfg(not(windows))]
21fn main() -> io::Result<()> {
22    let (stdin, stdout, stderr) = unsafe { (stdin(), stdout(), stderr()) };
23
24    println!("Stdin:");
25    show(&stdin)?;
26
27    println!("Stdout:");
28    show(&stdout)?;
29
30    println!("Stderr:");
31    show(&stderr)?;
32
33    Ok(())
34}
35
36#[cfg(not(windows))]
37fn show<Fd: AsFd>(fd: Fd) -> io::Result<()> {
38    let fd = fd.as_fd();
39    println!(" - ready: {:?}", rustix::io::ioctl_fionread(fd)?);
40
41    #[cfg(feature = "termios")]
42    if isatty(fd) {
43        #[cfg(feature = "procfs")]
44        #[cfg(not(target_os = "fuchsia"))]
45        println!(" - ttyname: {}", ttyname(fd, Vec::new())?.to_string_lossy());
46
47        #[cfg(target_os = "wasi")]
48        println!(" - is a tty");
49
50        #[cfg(not(target_os = "wasi"))]
51        println!(" - process group: {:?}", rustix::termios::tcgetpgrp(fd)?);
52
53        #[cfg(not(target_os = "wasi"))]
54        println!(" - winsize: {:?}", rustix::termios::tcgetwinsize(fd)?);
55
56        #[cfg(not(target_os = "wasi"))]
57        {
58            use rustix::termios::*;
59            let term = tcgetattr(fd)?;
60
61            if let Some(speed) = speed_value(cfgetispeed(&term)) {
62                println!(" - ispeed: {}", speed);
63            }
64            if let Some(speed) = speed_value(cfgetospeed(&term)) {
65                println!(" - ospeed: {}", speed);
66            }
67
68            print!(" - in flags:");
69            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
70            if (term.c_iflag & IGNBRK) != 0 {
71                print!(" IGNBRK");
72            }
73            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
74            if (term.c_iflag & BRKINT) != 0 {
75                print!(" BRKINT");
76            }
77            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
78            if (term.c_iflag & IGNPAR) != 0 {
79                print!(" IGNPAR");
80            }
81            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
82            if (term.c_iflag & PARMRK) != 0 {
83                print!(" PARMRK");
84            }
85            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
86            if (term.c_iflag & INPCK) != 0 {
87                print!(" INPCK");
88            }
89            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
90            if (term.c_iflag & ISTRIP) != 0 {
91                print!(" ISTRIP");
92            }
93            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
94            if (term.c_iflag & INLCR) != 0 {
95                print!(" INLCR");
96            }
97            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
98            if (term.c_iflag & IGNCR) != 0 {
99                print!(" IGNCR");
100            }
101            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
102            if (term.c_iflag & ICRNL) != 0 {
103                print!(" ICRNL");
104            }
105            #[cfg(any(
106                linux_raw,
107                all(
108                    libc,
109                    any(target_os = "haiku", target_os = "illumos", target_os = "solaris"),
110                )
111            ))]
112            if (term.c_iflag & IUCLC) != 0 {
113                print!(" IUCLC");
114            }
115            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
116            if (term.c_iflag & IXON) != 0 {
117                print!(" IXON");
118            }
119            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
120            if (term.c_iflag & IXANY) != 0 {
121                print!(" IXANY");
122            }
123            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
124            if (term.c_iflag & IXOFF) != 0 {
125                print!(" IXOFF");
126            }
127            #[cfg(not(any(target_os = "haiku", target_os = "ios", target_os = "macos")))]
128            if (term.c_iflag & IMAXBEL) != 0 {
129                print!(" IMAXBEL");
130            }
131            #[cfg(not(any(
132                target_os = "dragonfly",
133                target_os = "emscripten",
134                target_os = "freebsd",
135                target_os = "haiku",
136                target_os = "illumos",
137                target_os = "ios",
138                target_os = "macos",
139                target_os = "netbsd",
140                target_os = "openbsd",
141                target_os = "redox",
142                target_os = "solaris",
143            )))]
144            if (term.c_iflag & IUTF8) != 0 {
145                print!(" IUTF8");
146            }
147            println!();
148
149            print!(" - out flags:");
150            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
151            if (term.c_oflag & OPOST) != 0 {
152                print!(" OPOST");
153            }
154            #[cfg(not(any(
155                target_os = "dragonfly",
156                target_os = "freebsd",
157                target_os = "ios",
158                target_os = "macos",
159                target_os = "netbsd",
160                target_os = "redox",
161            )))]
162            if (term.c_oflag & OLCUC) != 0 {
163                print!(" OLCUC");
164            }
165            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
166            if (term.c_oflag & ONLCR) != 0 {
167                print!(" ONLCR");
168            }
169            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
170            if (term.c_oflag & OCRNL) != 0 {
171                print!(" OCRNL");
172            }
173            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
174            if (term.c_oflag & ONOCR) != 0 {
175                print!(" ONOCR");
176            }
177            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
178            if (term.c_oflag & ONLRET) != 0 {
179                print!(" ONLRET");
180            }
181            #[cfg(not(any(
182                target_os = "dragonfly",
183                target_os = "freebsd",
184                target_os = "ios",
185                target_os = "macos",
186                target_os = "netbsd",
187                target_os = "openbsd",
188            )))]
189            if (term.c_oflag & OFILL) != 0 {
190                print!(" OFILL");
191            }
192            #[cfg(not(any(
193                target_os = "dragonfly",
194                target_os = "freebsd",
195                target_os = "ios",
196                target_os = "macos",
197                target_os = "netbsd",
198                target_os = "openbsd",
199            )))]
200            if (term.c_oflag & OFDEL) != 0 {
201                print!(" OFDEL");
202            }
203            #[cfg(not(any(
204                target_os = "dragonfly",
205                target_os = "freebsd",
206                target_os = "illumos",
207                target_os = "ios",
208                target_os = "macos",
209                target_os = "netbsd",
210                target_os = "openbsd",
211                target_os = "redox",
212                target_os = "solaris",
213            )))]
214            if (term.c_oflag & NLDLY) != 0 {
215                print!(" NLDLY");
216            }
217            #[cfg(not(any(
218                target_os = "dragonfly",
219                target_os = "freebsd",
220                target_os = "illumos",
221                target_os = "ios",
222                target_os = "macos",
223                target_os = "netbsd",
224                target_os = "openbsd",
225                target_os = "redox",
226                target_os = "solaris",
227            )))]
228            if (term.c_oflag & CRDLY) != 0 {
229                print!(" CRDLY");
230            }
231            #[cfg(not(any(
232                target_os = "dragonfly",
233                target_os = "ios",
234                target_os = "macos",
235                target_os = "netbsd",
236                target_os = "openbsd",
237                target_os = "illumos",
238                target_os = "redox",
239                target_os = "solaris",
240            )))]
241            if (term.c_oflag & TABDLY) != 0 {
242                print!(" TABDLY");
243            }
244            #[cfg(not(any(
245                target_os = "dragonfly",
246                target_os = "freebsd",
247                target_os = "illumos",
248                target_os = "ios",
249                target_os = "macos",
250                target_os = "netbsd",
251                target_os = "openbsd",
252                target_os = "redox",
253                target_os = "solaris",
254            )))]
255            if (term.c_oflag & BSDLY) != 0 {
256                print!(" BSDLY");
257            }
258            #[cfg(not(any(
259                all(libc, target_env = "musl"),
260                target_os = "dragonfly",
261                target_os = "freebsd",
262                target_os = "illumos",
263                target_os = "ios",
264                target_os = "macos",
265                target_os = "netbsd",
266                target_os = "openbsd",
267                target_os = "redox",
268                target_os = "solaris",
269            )))]
270            if (term.c_oflag & VTDLY) != 0 {
271                print!(" VTDLY");
272            }
273            #[cfg(not(any(
274                all(libc, target_env = "musl"),
275                target_os = "dragonfly",
276                target_os = "freebsd",
277                target_os = "illumos",
278                target_os = "ios",
279                target_os = "macos",
280                target_os = "netbsd",
281                target_os = "openbsd",
282                target_os = "redox",
283                target_os = "solaris",
284            )))]
285            if (term.c_oflag & FFDLY) != 0 {
286                print!(" FFDLY");
287            }
288            println!();
289
290            print!(" - control flags:");
291            #[cfg(not(any(
292                target_os = "dragonfly",
293                target_os = "freebsd",
294                target_os = "haiku",
295                target_os = "ios",
296                target_os = "macos",
297                target_os = "netbsd",
298                target_os = "openbsd",
299                target_os = "redox",
300            )))]
301            if (term.c_cflag & CBAUD) != 0 {
302                print!(" CBAUD");
303            }
304            #[cfg(not(any(
305                target_os = "dragonfly",
306                target_os = "freebsd",
307                target_os = "haiku",
308                target_os = "illumos",
309                target_os = "ios",
310                target_os = "macos",
311                target_os = "netbsd",
312                target_os = "openbsd",
313                target_os = "redox",
314                target_os = "solaris",
315            )))]
316            if (term.c_cflag & CBAUDEX) != 0 {
317                print!(" CBAUDEX");
318            }
319            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
320            if (term.c_cflag & CSIZE) != 0 {
321                print!(" CSIZE");
322            }
323            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
324            if (term.c_cflag & CSTOPB) != 0 {
325                print!(" CSTOPB");
326            }
327            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
328            if (term.c_cflag & CREAD) != 0 {
329                print!(" CREAD");
330            }
331            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
332            if (term.c_cflag & PARENB) != 0 {
333                print!(" PARENB");
334            }
335            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
336            if (term.c_cflag & PARODD) != 0 {
337                print!(" PARODD");
338            }
339            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
340            if (term.c_cflag & HUPCL) != 0 {
341                print!(" HUPCL");
342            }
343            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
344            if (term.c_cflag & CLOCAL) != 0 {
345                print!(" CLOCAL");
346            }
347            #[cfg(not(any(
348                target_os = "dragonfly",
349                target_os = "emscripten",
350                target_os = "freebsd",
351                target_os = "haiku",
352                target_os = "ios",
353                target_os = "macos",
354                target_os = "netbsd",
355                target_os = "openbsd",
356                target_os = "redox",
357            )))]
358            if (term.c_cflag & CIBAUD) != 0 {
359                print!(" CIBAUD");
360            }
361            #[cfg(not(any(
362                target_os = "dragonfly",
363                target_os = "emscripten",
364                target_os = "freebsd",
365                target_os = "haiku",
366                target_os = "illumos",
367                target_os = "ios",
368                target_os = "macos",
369                target_os = "netbsd",
370                target_os = "openbsd",
371                target_os = "redox",
372                target_os = "solaris",
373            )))]
374            if (term.c_cflag & CMSPAR) != 0 {
375                print!(" CMSPAR");
376            }
377            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
378            if (term.c_cflag & CRTSCTS) != 0 {
379                print!(" CRTSCTS");
380            }
381            println!();
382
383            print!(" - local flags:");
384            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
385            if (term.c_lflag & ISIG) != 0 {
386                print!(" ISIG");
387            }
388            if (term.c_lflag & ICANON) != 0 {
389                print!(" ICANON");
390            }
391            #[cfg(any(linux_raw, all(libc, any(target_arch = "s390x", target_os = "haiku"))))]
392            if (term.c_lflag & XCASE) != 0 {
393                print!(" XCASE");
394            }
395            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
396            if (term.c_lflag & ECHO) != 0 {
397                print!(" ECHO");
398            }
399            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
400            if (term.c_lflag & ECHOE) != 0 {
401                print!(" ECHOE");
402            }
403            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
404            if (term.c_lflag & ECHOK) != 0 {
405                print!(" ECHOK");
406            }
407            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
408            if (term.c_lflag & ECHONL) != 0 {
409                print!(" ECHONL");
410            }
411            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
412            if (term.c_lflag & ECHOCTL) != 0 {
413                print!(" ECHOCTL");
414            }
415            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
416            if (term.c_lflag & ECHOPRT) != 0 {
417                print!(" ECHOPRT");
418            }
419            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
420            if (term.c_lflag & ECHOKE) != 0 {
421                print!(" ECHOKE");
422            }
423            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
424            if (term.c_lflag & FLUSHO) != 0 {
425                print!(" FLUSHO");
426            }
427            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
428            if (term.c_lflag & NOFLSH) != 0 {
429                print!(" NOFLSH");
430            }
431            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
432            if (term.c_lflag & TOSTOP) != 0 {
433                print!(" TOSTOP");
434            }
435            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
436            if (term.c_lflag & PENDIN) != 0 {
437                print!(" PENDIN");
438            }
439            #[cfg(not(any(target_os = "ios", target_os = "macos")))]
440            if (term.c_lflag & IEXTEN) != 0 {
441                print!(" IEXTEN");
442            }
443            println!();
444
445            println!(
446                " - keys: INTR={} QUIT={} ERASE={} KILL={} EOF={} TIME={} MIN={} ",
447                key(term.c_cc[VINTR]),
448                key(term.c_cc[VQUIT]),
449                key(term.c_cc[VERASE]),
450                key(term.c_cc[VKILL]),
451                key(term.c_cc[VEOF]),
452                term.c_cc[VTIME],
453                term.c_cc[VMIN]
454            );
455            println!(
456                "         START={} STOP={} SUSP={} EOL={}",
457                key(term.c_cc[VSTART]),
458                key(term.c_cc[VSTOP]),
459                key(term.c_cc[VSUSP]),
460                key(term.c_cc[VEOL]),
461            );
462            #[cfg(not(target_os = "haiku"))]
463            println!(
464                "         REPRINT={} DISCARD={}",
465                key(term.c_cc[VREPRINT]),
466                key(term.c_cc[VDISCARD])
467            );
468            #[cfg(not(target_os = "haiku"))]
469            println!(
470                "         WERASE={} VLNEXT={}",
471                key(term.c_cc[VWERASE]),
472                key(term.c_cc[VLNEXT]),
473            );
474            println!("         EOL2={}", key(term.c_cc[VEOL2]));
475        }
476    } else {
477        println!(" - is not a tty");
478    }
479
480    println!();
481    Ok(())
482}
483
484#[cfg(feature = "termios")]
485#[cfg(not(windows))]
486fn key(b: u8) -> String {
487    if b == 0 {
488        format!("<undef>")
489    } else if b < 0x20 {
490        format!("^{}", (b + 0x40) as char)
491    } else if b == 0x7f {
492        format!("^?")
493    } else {
494        format!("{}", b as char)
495    }
496}
497
498#[cfg(windows)]
499fn main() {
500    unimplemented!()
501}
502