@@ -31,7 +31,7 @@ impl Drop for DynamicLibrary {
31
31
dl : : close( self . handle)
32
32
}
33
33
} {
34
- Ok ( ( ) ) => { } ,
34
+ Ok ( ( ) ) => { } ,
35
35
Err ( str) => fail ! ( str )
36
36
}
37
37
}
@@ -41,14 +41,20 @@ impl DynamicLibrary {
41
41
/// Lazily open a dynamic library. When passed None it gives a
42
42
/// handle to the calling process
43
43
pub fn open ( filename : Option < & path:: Path > ) -> Result < DynamicLibrary , ~str > {
44
- do dl:: check_for_errors_in {
45
- unsafe {
46
- DynamicLibrary { handle :
47
- match filename {
48
- Some ( name) => dl:: open_external ( name) ,
49
- None => dl:: open_internal ( )
50
- }
44
+ unsafe {
45
+ let maybe_library = do dl:: check_for_errors_in {
46
+ match filename {
47
+ Some ( name) => dl:: open_external ( name) ,
48
+ None => dl:: open_internal ( )
51
49
}
50
+ } ;
51
+
52
+ // The dynamic library must not be constructed if there is
53
+ // an error opening the library so the destructor does not
54
+ // run.
55
+ match maybe_library {
56
+ Err ( err) => Err ( err) ,
57
+ Ok ( handle) => Ok ( DynamicLibrary { handle: handle } )
52
58
}
53
59
}
54
60
}
@@ -58,41 +64,69 @@ impl DynamicLibrary {
58
64
// This function should have a lifetime constraint of 'self on
59
65
// T but that feature is still unimplemented
60
66
61
- do dl:: check_for_errors_in {
62
- let symbol_value = do symbol. as_c_str |raw_string| {
67
+ let maybe_symbol_value = do dl:: check_for_errors_in {
68
+ do symbol. as_c_str |raw_string| {
63
69
dl:: symbol ( self . handle , raw_string)
64
- } ;
70
+ }
71
+ } ;
65
72
66
- cast:: transmute ( symbol_value)
73
+ // The value must not be constructed if there is an error so
74
+ // the destructor does not run.
75
+ match maybe_symbol_value {
76
+ Err ( err) => Err ( err) ,
77
+ Ok ( symbol_value) => Ok ( cast:: transmute ( symbol_value) )
67
78
}
68
79
}
69
80
}
70
81
71
- #[ test]
72
- #[ ignore( cfg( windows) ) ]
73
- priv fn test_loading_cosine ( ) {
74
- // The math library does not need to be loaded since it is already
75
- // statically linked in
76
- let libm = match DynamicLibrary :: open ( None ) {
77
- Err ( error) => fail ! ( "Could not load self as module: %s" , error) ,
78
- Ok ( libm) => libm
79
- } ;
80
-
81
- // Unfortunately due to issue #6194 it is not possible to call
82
- // this as a C function
83
- let cosine: extern fn ( libc:: c_double ) -> libc:: c_double = unsafe {
84
- match libm. symbol ( "cos" ) {
85
- Err ( error) => fail ! ( "Could not load function cos: %s" , error) ,
86
- Ok ( cosine) => cosine
82
+
83
+ #[ cfg( test) ]
84
+ mod test {
85
+ use super :: * ;
86
+ use option:: * ;
87
+ use result:: * ;
88
+ use path:: * ;
89
+ use libc;
90
+
91
+ #[ test]
92
+ fn test_loading_cosine ( ) {
93
+ // The math library does not need to be loaded since it is already
94
+ // statically linked in
95
+ let libm = match DynamicLibrary :: open ( None ) {
96
+ Err ( error) => fail ! ( "Could not load self as module: %s" , error) ,
97
+ Ok ( libm) => libm
98
+ } ;
99
+
100
+ // Unfortunately due to issue #6194 it is not possible to call
101
+ // this as a C function
102
+ let cosine: extern fn ( libc:: c_double ) -> libc:: c_double = unsafe {
103
+ match libm. symbol ( "cos" ) {
104
+ Err ( error) => fail ! ( "Could not load function cos: %s" , error) ,
105
+ Ok ( cosine) => cosine
106
+ }
107
+ } ;
108
+
109
+ let argument = 0.0 ;
110
+ let expected_result = 1.0 ;
111
+ let result = cosine ( argument) ;
112
+ if result != expected_result {
113
+ fail ! ( "cos(%?) != %? but equaled %? instead" , argument,
114
+ expected_result, result)
115
+ }
116
+ }
117
+
118
+ #[ test]
119
+ #[ cfg( target_os = "linux" ) ]
120
+ #[ cfg( target_os = "macos" ) ]
121
+ #[ cfg( target_os = "freebsd" ) ]
122
+ fn test_errors_do_not_crash ( ) {
123
+ // Open /dev/null as a library to get an error, and make sure
124
+ // that only causes an error, and not a crash.
125
+ let path = GenericPath :: from_str ( "/dev/null" ) ;
126
+ match DynamicLibrary :: open ( Some ( & path) ) {
127
+ Err ( _) => { }
128
+ Ok ( _) => fail ! ( "Successfully opened the empty library." )
87
129
}
88
- } ;
89
-
90
- let argument = 0.0 ;
91
- let expected_result = 1.0 ;
92
- let result = cosine ( argument) ;
93
- if result != expected_result {
94
- fail ! ( "cos(%?) != %? but equaled %? instead" , argument,
95
- expected_result, result)
96
130
}
97
131
}
98
132
0 commit comments