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))]
7 use rustix::fd::AsFd;
8 #[cfg(not(windows))]
9 use rustix::io::{self, stderr, stdin, stdout};
10 #[cfg(feature = "termios")]
11 #[cfg(not(windows))]
12 use rustix::termios::isatty;
13 #[cfg(all(
14 not(any(windows, target_os = "fuchsia")),
15 feature = "termios",
16 feature = "procfs"
17 ))]
18 use rustix::termios::ttyname;
19
20 #[cfg(not(windows))]
main() -> io::Result<()>21 fn 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))]
show<Fd: AsFd>(fd: Fd) -> io::Result<()>37 fn 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))]
key(b: u8) -> String486 fn 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)]
main()499 fn main() {
500 unimplemented!()
501 }
502