(index<- )        ./libstd/io/tempfile.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
  1  // Copyright 2013 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  
 11  //! Temporary files and directories
 12  
 13  use io::fs;
 14  use io;
 15  use iter::{Iterator, range};
 16  use libc;
 17  use ops::Drop;
 18  use option::{Option, None, Some};
 19  use os;
 20  use path::{Path, GenericPath};
 21  use result::{Ok, Err, ResultUnwrap};
 22  use sync::atomics;
 23  
 24  /// A wrapper for a path to temporary directory implementing automatic
 25  /// scope-based deletion.
 26  pub struct TempDir {
 27      path: Option<Path>
 28  }
 29  
 30  impl TempDir {
 31      /// Attempts to make a temporary directory inside of `tmpdir` whose name
 32      /// will have the suffix `suffix`. The directory will be automatically
 33      /// deleted once the returned wrapper is destroyed.
 34      ///
 35      /// If no directory can be created, None is returned.
 36      pub fn new_in(tmpdir&Path, suffix&str) -> Option<TempDir> {
 37          if !tmpdir.is_absolute() {
 38              return TempDir::new_in(&os::make_absolute(tmpdir), suffix);
 39          }
 40  
 41          static mut CNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
 42  
 43          for _ in range(0u, 1000) {
 44              let filename = format!("rs-{}-{}-{}",
 45                                     unsafe { libc::getpid() },
 46                                     unsafe { CNT.fetch_add(1, atomics::SeqCst) },
 47                                     suffix);
 48              let p = tmpdir.join(filename);
 49              match fs::mkdir(&p, io::UserRWX) {
 50                  Err(..) => {}
 51                  Ok(()) => return Some(TempDir { path: Some(p) })
 52              }
 53          }
 54          None
 55      }
 56  
 57      /// Attempts to make a temporary directory inside of `os::tmpdir()` whose
 58      /// name will have the suffix `suffix`. The directory will be automatically
 59      /// deleted once the returned wrapper is destroyed.
 60      ///
 61      /// If no directory can be created, None is returned.
 62      pub fn new(suffix&str) -> Option<TempDir> {
 63          TempDir::new_in(&os::tmpdir(), suffix)
 64      }
 65  
 66      /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
 67      /// This discards the wrapper so that the automatic deletion of the
 68      /// temporary directory is prevented.
 69      pub fn unwrap(self) -> Path {
 70          let mut tmpdir = self;
 71          tmpdir.path.take_unwrap()
 72      }
 73  
 74      /// Access the wrapped `std::path::Path` to the temporary directory.
 75      pub fn path<'a>(&'a self) -> &'a Path {
 76          self.path.get_ref()
 77      }
 78  }
 79  
 80  impl Drop for TempDir {
 81      fn drop(&mut self) {
 82          for path in self.path.iter() {
 83              if path.exists() {
 84                  // FIXME: is failing the right thing to do?
 85                  fs::rmdir_recursive(path).unwrap();
 86              }
 87          }
 88      }
 89  }
 90  
 91  // the tests for this module need to change the path using change_dir,
 92  // and this doesn't play nicely with other tests so these unit tests are located
 93  // in src/test/run-pass/tempfile.rs