/src/test/run-pass/fds-are-cloexec.rs

http://github.com/eholk/rust · Rust · 90 lines · 67 code · 10 blank · 13 comment · 5 complexity · c5253cdc8f5d55efbd1a4655da21cb00 MD5 · raw file

  1. // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. // ignore-windows
  11. // ignore-android
  12. // ignore-emscripten
  13. // ignore-haiku
  14. #![feature(libc)]
  15. extern crate libc;
  16. use std::env;
  17. use std::fs::File;
  18. use std::io;
  19. use std::net::{TcpListener, TcpStream, UdpSocket};
  20. use std::os::unix::prelude::*;
  21. use std::process::{Command, Stdio};
  22. use std::thread;
  23. fn main() {
  24. let args = env::args().collect::<Vec<_>>();
  25. if args.len() == 1 {
  26. parent()
  27. } else {
  28. child(&args)
  29. }
  30. }
  31. fn parent() {
  32. let file = File::open(env::current_exe().unwrap()).unwrap();
  33. let tcp1 = TcpListener::bind("127.0.0.1:0").unwrap();
  34. let tcp2 = tcp1.try_clone().unwrap();
  35. let addr = tcp1.local_addr().unwrap();
  36. let t = thread::spawn(move || TcpStream::connect(addr).unwrap());
  37. let tcp3 = tcp1.accept().unwrap().0;
  38. let tcp4 = t.join().unwrap();
  39. let tcp5 = tcp3.try_clone().unwrap();
  40. let tcp6 = tcp4.try_clone().unwrap();
  41. let udp1 = UdpSocket::bind("127.0.0.1:0").unwrap();
  42. let udp2 = udp1.try_clone().unwrap();
  43. let mut child = Command::new(env::args().next().unwrap())
  44. .arg("100")
  45. .stdout(Stdio::piped())
  46. .stdin(Stdio::piped())
  47. .stderr(Stdio::piped())
  48. .spawn().unwrap();
  49. let pipe1 = child.stdin.take().unwrap();
  50. let pipe2 = child.stdout.take().unwrap();
  51. let pipe3 = child.stderr.take().unwrap();
  52. let status = Command::new(env::args().next().unwrap())
  53. .arg(file.as_raw_fd().to_string())
  54. .arg(tcp1.as_raw_fd().to_string())
  55. .arg(tcp2.as_raw_fd().to_string())
  56. .arg(tcp3.as_raw_fd().to_string())
  57. .arg(tcp4.as_raw_fd().to_string())
  58. .arg(tcp5.as_raw_fd().to_string())
  59. .arg(tcp6.as_raw_fd().to_string())
  60. .arg(udp1.as_raw_fd().to_string())
  61. .arg(udp2.as_raw_fd().to_string())
  62. .arg(pipe1.as_raw_fd().to_string())
  63. .arg(pipe2.as_raw_fd().to_string())
  64. .arg(pipe3.as_raw_fd().to_string())
  65. .status()
  66. .unwrap();
  67. assert!(status.success());
  68. child.wait().unwrap();
  69. }
  70. fn child(args: &[String]) {
  71. let mut b = [0u8; 2];
  72. for arg in &args[1..] {
  73. let fd: libc::c_int = arg.parse().unwrap();
  74. unsafe {
  75. assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1);
  76. assert_eq!(io::Error::last_os_error().raw_os_error(),
  77. Some(libc::EBADF));
  78. }
  79. }
  80. }