Skip to content

Commit 6e2d2e3

Browse files
committed
---
yaml --- r: 80770 b: refs/heads/try c: 940a86b h: refs/heads/master v: v3
1 parent d737805 commit 6e2d2e3

File tree

10 files changed

+182
-264
lines changed

10 files changed

+182
-264
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 4c6bf4872012c010f84dc7fa2cdfe87522533f89
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cbd1eefbd350797b783df119fed7956d7e1c74ad
5-
refs/heads/try: 4ac10f8f6e8e07c70fadb676170c5402442e2243
5+
refs/heads/try: 940a86b760bc56d9cd54238201a2206a9d55c70c
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libextra/tempfile.rs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,97 @@ pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
2828
None
2929
}
3030

31-
// the tests for this module need to change the path using change_dir,
32-
// and this doesn't play nicely with other tests so these unit tests are located
33-
// in src/test/run-pass/tempfile.rs
31+
#[cfg(test)]
32+
mod tests {
33+
34+
use tempfile::mkdtemp;
35+
36+
use std::os;
37+
38+
#[test]
39+
fn test_mkdtemp() {
40+
let p = mkdtemp(&Path("."), "foobar").unwrap();
41+
os::remove_dir(&p);
42+
assert!(p.to_str().ends_with("foobar"));
43+
}
44+
45+
// Ideally these would be in std::os but then core would need
46+
// to depend on std
47+
#[test]
48+
fn recursive_mkdir_rel() {
49+
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
50+
use std::os;
51+
use std::unstable::change_dir_locked;
52+
53+
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
54+
expect("recursive_mkdir_rel");
55+
assert!(do change_dir_locked(&root) {
56+
let path = Path("frob");
57+
debug!("recursive_mkdir_rel: Making: %s in cwd %s [%?]", path.to_str(),
58+
os::getcwd().to_str(),
59+
os::path_exists(&path));
60+
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
61+
assert!(os::path_is_dir(&path));
62+
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
63+
assert!(os::path_is_dir(&path));
64+
});
65+
}
66+
67+
#[test]
68+
fn recursive_mkdir_dot() {
69+
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
70+
use std::os;
71+
72+
let dot = Path(".");
73+
assert!(os::mkdir_recursive(&dot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
74+
let dotdot = Path("..");
75+
assert!(os::mkdir_recursive(&dotdot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
76+
}
77+
78+
#[test]
79+
fn recursive_mkdir_rel_2() {
80+
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
81+
use std::os;
82+
use std::unstable::change_dir_locked;
83+
84+
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
85+
expect("recursive_mkdir_rel_2");
86+
assert!(do change_dir_locked(&root) {
87+
let path = Path("./frob/baz");
88+
debug!("recursive_mkdir_rel_2: Making: %s in cwd %s [%?]", path.to_str(),
89+
os::getcwd().to_str(), os::path_exists(&path));
90+
assert!(os::mkdir_recursive(&path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
91+
assert!(os::path_is_dir(&path));
92+
assert!(os::path_is_dir(&path.pop()));
93+
let path2 = Path("quux/blat");
94+
debug!("recursive_mkdir_rel_2: Making: %s in cwd %s", path2.to_str(),
95+
os::getcwd().to_str());
96+
assert!(os::mkdir_recursive(&path2, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
97+
assert!(os::path_is_dir(&path2));
98+
assert!(os::path_is_dir(&path2.pop()));
99+
});
100+
}
101+
102+
// Ideally this would be in core, but needs mkdtemp
103+
#[test]
104+
pub fn test_rmdir_recursive_ok() {
105+
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
106+
use std::os;
107+
108+
let rwx = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;
109+
110+
let tmpdir = mkdtemp(&os::tmpdir(), "test").expect("test_rmdir_recursive_ok: \
111+
couldn't create temp dir");
112+
let root = tmpdir.push("foo");
113+
114+
debug!("making %s", root.to_str());
115+
assert!(os::make_dir(&root, rwx));
116+
assert!(os::make_dir(&root.push("foo"), rwx));
117+
assert!(os::make_dir(&root.push("foo").push("bar"), rwx));
118+
assert!(os::make_dir(&root.push("foo").push("bar").push("blat"), rwx));
119+
assert!(os::remove_dir_recursive(&root));
120+
assert!(!os::path_exists(&root));
121+
assert!(!os::path_exists(&root.push("bar")));
122+
assert!(!os::path_exists(&root.push("bar").push("blat")));
123+
}
124+
}

branches/try/src/librustpkg/tests.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -819,25 +819,26 @@ fn rust_path_test() {
819819
}
820820
821821
#[test]
822-
#[ignore] // FIXME(#9184) tests can't change the cwd (other tests are sad then)
823822
fn rust_path_contents() {
823+
use std::unstable::change_dir_locked;
824+
824825
let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
825826
let abc = &dir.push("A").push("B").push("C");
826827
assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX));
827828
assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX));
828829
assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX));
829-
assert!(os::change_dir(abc));
830-
831-
let p = rust_path();
832-
let cwd = os::getcwd().push(".rust");
833-
let parent = cwd.pop().pop().push(".rust");
834-
let grandparent = cwd.pop().pop().pop().push(".rust");
835-
assert!(p.contains(&cwd));
836-
assert!(p.contains(&parent));
837-
assert!(p.contains(&grandparent));
838-
for a_path in p.iter() {
839-
assert!(!a_path.components.is_empty());
840-
}
830+
assert!(do change_dir_locked(&dir.push("A").push("B").push("C")) {
831+
let p = rust_path();
832+
let cwd = os::getcwd().push(".rust");
833+
let parent = cwd.pop().pop().push(".rust");
834+
let grandparent = cwd.pop().pop().pop().push(".rust");
835+
assert!(p.contains(&cwd));
836+
assert!(p.contains(&parent));
837+
assert!(p.contains(&grandparent));
838+
for a_path in p.iter() {
839+
assert!(!a_path.components.is_empty());
840+
}
841+
});
841842
}
842843
843844
#[test]

branches/try/src/libstd/unstable/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,59 @@ fn test_run_in_bare_thread_exchange() {
6868
}
6969
}
7070

71+
72+
/// Changes the current working directory to the specified
73+
/// path while acquiring a global lock, then calls `action`.
74+
/// If the change is successful, releases the lock and restores the
75+
/// CWD to what it was before, returning true.
76+
/// Returns false if the directory doesn't exist or if the directory change
77+
/// is otherwise unsuccessful.
78+
///
79+
/// This is used by test cases to avoid cwd races.
80+
///
81+
/// # Safety Note
82+
///
83+
/// This uses a pthread mutex so descheduling in the action callback
84+
/// can lead to deadlock. Calling change_dir_locked recursively will
85+
/// also deadlock.
86+
pub fn change_dir_locked(p: &Path, action: &fn()) -> bool {
87+
#[fixed_stack_segment]; #[inline(never)];
88+
89+
use os;
90+
use os::change_dir;
91+
use unstable::sync::atomically;
92+
use unstable::finally::Finally;
93+
94+
unsafe {
95+
// This is really sketchy. Using a pthread mutex so descheduling
96+
// in the `action` callback can cause deadlock. Doing it in
97+
// `task::atomically` to try to avoid that, but ... I don't know
98+
// this is all bogus.
99+
return do atomically {
100+
rust_take_change_dir_lock();
101+
102+
do (||{
103+
let old_dir = os::getcwd();
104+
if change_dir(p) {
105+
action();
106+
change_dir(&old_dir)
107+
}
108+
else {
109+
false
110+
}
111+
}).finally {
112+
rust_drop_change_dir_lock();
113+
}
114+
}
115+
}
116+
117+
extern {
118+
fn rust_take_change_dir_lock();
119+
fn rust_drop_change_dir_lock();
120+
}
121+
}
122+
123+
71124
/// Dynamically inquire about whether we're running under V.
72125
/// You should usually not use this unless your test definitely
73126
/// can't run correctly un-altered. Valgrind is there to help

branches/try/src/libsyntax/ast_util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -15,7 +15,7 @@ use codemap::{Span, dummy_sp};
1515
use fold;
1616
use opt_vec;
1717
use parse::token;
18-
use visit::{SimpleVisitor, Visitor};
18+
use visit::Visitor;
1919
use visit;
2020

2121
use std::hashmap::HashMap;

branches/try/src/libsyntax/visit.rs

Lines changed: 1 addition & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -668,144 +668,3 @@ pub fn walk_arm<E:Clone, V:Visitor<E>>(visitor: &mut V, arm: &Arm, env: E) {
668668
walk_expr_opt(visitor, arm.guard, env.clone());
669669
visitor.visit_block(&arm.body, env)
670670
}
671-
672-
// Simpler, non-context passing interface. Always walks the whole tree, simply
673-
// calls the given functions on the nodes.
674-
675-
pub trait SimpleVisitor {
676-
fn visit_mod(&mut self, &_mod, Span, NodeId);
677-
fn visit_view_item(&mut self, &view_item);
678-
fn visit_foreign_item(&mut self, @foreign_item);
679-
fn visit_item(&mut self, @item);
680-
fn visit_local(&mut self, @Local);
681-
fn visit_block(&mut self, &Block);
682-
fn visit_stmt(&mut self, @Stmt);
683-
fn visit_arm(&mut self, &Arm);
684-
fn visit_pat(&mut self, @Pat);
685-
fn visit_decl(&mut self, @Decl);
686-
fn visit_expr(&mut self, @Expr);
687-
fn visit_expr_post(&mut self, @Expr);
688-
fn visit_ty(&mut self, &Ty);
689-
fn visit_generics(&mut self, &Generics);
690-
fn visit_fn(&mut self, &fn_kind, &fn_decl, &Block, Span, NodeId);
691-
fn visit_ty_method(&mut self, &TypeMethod);
692-
fn visit_trait_method(&mut self, &trait_method);
693-
fn visit_struct_def(&mut self, @struct_def, Ident, &Generics, NodeId);
694-
fn visit_struct_field(&mut self, @struct_field);
695-
fn visit_struct_method(&mut self, @method);
696-
}
697-
698-
pub struct SimpleVisitorVisitor {
699-
simple_visitor: @mut SimpleVisitor,
700-
}
701-
702-
impl Visitor<()> for SimpleVisitorVisitor {
703-
fn visit_mod(&mut self,
704-
module: &_mod,
705-
span: Span,
706-
node_id: NodeId,
707-
env: ()) {
708-
self.simple_visitor.visit_mod(module, span, node_id);
709-
walk_mod(self, module, env)
710-
}
711-
fn visit_view_item(&mut self, view_item: &view_item, env: ()) {
712-
self.simple_visitor.visit_view_item(view_item);
713-
walk_view_item(self, view_item, env)
714-
}
715-
fn visit_foreign_item(&mut self, foreign_item: @foreign_item, env: ()) {
716-
self.simple_visitor.visit_foreign_item(foreign_item);
717-
walk_foreign_item(self, foreign_item, env)
718-
}
719-
fn visit_item(&mut self, item: @item, env: ()) {
720-
self.simple_visitor.visit_item(item);
721-
walk_item(self, item, env)
722-
}
723-
fn visit_local(&mut self, local: @Local, env: ()) {
724-
self.simple_visitor.visit_local(local);
725-
walk_local(self, local, env)
726-
}
727-
fn visit_block(&mut self, block: &Block, env: ()) {
728-
self.simple_visitor.visit_block(block);
729-
walk_block(self, block, env)
730-
}
731-
fn visit_stmt(&mut self, statement: @Stmt, env: ()) {
732-
self.simple_visitor.visit_stmt(statement);
733-
walk_stmt(self, statement, env)
734-
}
735-
fn visit_arm(&mut self, arm: &Arm, env: ()) {
736-
self.simple_visitor.visit_arm(arm);
737-
walk_arm(self, arm, env)
738-
}
739-
fn visit_pat(&mut self, pattern: @Pat, env: ()) {
740-
self.simple_visitor.visit_pat(pattern);
741-
walk_pat(self, pattern, env)
742-
}
743-
fn visit_decl(&mut self, declaration: @Decl, env: ()) {
744-
self.simple_visitor.visit_decl(declaration);
745-
walk_decl(self, declaration, env)
746-
}
747-
fn visit_expr(&mut self, expression: @Expr, env: ()) {
748-
self.simple_visitor.visit_expr(expression);
749-
walk_expr(self, expression, env)
750-
}
751-
fn visit_expr_post(&mut self, expression: @Expr, _: ()) {
752-
self.simple_visitor.visit_expr_post(expression)
753-
}
754-
fn visit_ty(&mut self, typ: &Ty, env: ()) {
755-
self.simple_visitor.visit_ty(typ);
756-
walk_ty(self, typ, env)
757-
}
758-
fn visit_generics(&mut self, generics: &Generics, env: ()) {
759-
self.simple_visitor.visit_generics(generics);
760-
walk_generics(self, generics, env)
761-
}
762-
fn visit_fn(&mut self,
763-
function_kind: &fn_kind,
764-
function_declaration: &fn_decl,
765-
block: &Block,
766-
span: Span,
767-
node_id: NodeId,
768-
env: ()) {
769-
self.simple_visitor.visit_fn(function_kind,
770-
function_declaration,
771-
block,
772-
span,
773-
node_id);
774-
walk_fn(self,
775-
function_kind,
776-
function_declaration,
777-
block,
778-
span,
779-
node_id,
780-
env)
781-
}
782-
fn visit_ty_method(&mut self, method_type: &TypeMethod, env: ()) {
783-
self.simple_visitor.visit_ty_method(method_type);
784-
walk_ty_method(self, method_type, env)
785-
}
786-
fn visit_trait_method(&mut self, trait_method: &trait_method, env: ()) {
787-
self.simple_visitor.visit_trait_method(trait_method);
788-
walk_trait_method(self, trait_method, env)
789-
}
790-
fn visit_struct_def(&mut self,
791-
struct_definition: @struct_def,
792-
identifier: Ident,
793-
generics: &Generics,
794-
node_id: NodeId,
795-
env: ()) {
796-
self.simple_visitor.visit_struct_def(struct_definition,
797-
identifier,
798-
generics,
799-
node_id);
800-
walk_struct_def(self,
801-
struct_definition,
802-
identifier,
803-
generics,
804-
node_id,
805-
env)
806-
}
807-
fn visit_struct_field(&mut self, struct_field: @struct_field, env: ()) {
808-
self.simple_visitor.visit_struct_field(struct_field);
809-
walk_struct_field(self, struct_field, env)
810-
}
811-
}

branches/try/src/rt/rust_builtin.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,18 @@ rust_get_global_args_ptr() {
603603
return &global_args_ptr;
604604
}
605605

606+
static lock_and_signal change_dir_lock;
607+
608+
extern "C" CDECL void
609+
rust_take_change_dir_lock() {
610+
change_dir_lock.lock();
611+
}
612+
613+
extern "C" CDECL void
614+
rust_drop_change_dir_lock() {
615+
change_dir_lock.unlock();
616+
}
617+
606618
// Used by i386 __morestack
607619
extern "C" CDECL uintptr_t
608620
rust_get_task() {

0 commit comments

Comments
 (0)