@@ -31,7 +31,7 @@ impl Drop for DynamicLibrary {
3131 dl : : close( self . handle)
3232 }
3333 } {
34- Ok ( ( ) ) => { } ,
34+ Ok ( ( ) ) => { } ,
3535 Err ( str) => fail ! ( str )
3636 }
3737 }
@@ -41,14 +41,20 @@ impl DynamicLibrary {
4141 /// Lazily open a dynamic library. When passed None it gives a
4242 /// handle to the calling process
4343 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 ( )
5149 }
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 } )
5258 }
5359 }
5460 }
@@ -58,41 +64,69 @@ impl DynamicLibrary {
5864 // This function should have a lifetime constraint of 'self on
5965 // T but that feature is still unimplemented
6066
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| {
6369 dl:: symbol ( self . handle , raw_string)
64- } ;
70+ }
71+ } ;
6572
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) )
6778 }
6879 }
6980}
7081
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." )
87129 }
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)
96130 }
97131}
98132
0 commit comments