diff --git a/dynlib.carp b/dynlib.carp index 454a8f4..22dfc3a 100644 --- a/dynlib.carp +++ b/dynlib.carp @@ -62,10 +62,10 @@ a shared library `lib`. Returns a `Result` with the function on success, or the f (dlsym lib (cstr &fqn))] (if (valid? f) (Result.Success @f) (Result.Error (dlerror))))) - (doc close "closes a library `lib`. Either returns nothing or, if an error -occurs, it returns the error message.") + (doc close "closes a library `lib`. Returns a `Result` with `()` on success, +or the `dlerror` message on failure.") (defn close [lib] - (if (= -1 (dlclose lib)) (Maybe.Just (dlerror)) (Maybe.Nothing))) + (if (/= 0 (dlclose lib)) (Result.Error (dlerror)) (Result.Success ()))) (defmacro rebind [lib s] (list 'match diff --git a/test/dynlib.carp b/test/dynlib.carp new file mode 100644 index 0000000..5cf782a --- /dev/null +++ b/test/dynlib.carp @@ -0,0 +1,56 @@ +(load "../dynlib.carp") +(load "Test.carp") +(use Test) + +(defn main [] + (with-test test + ; open succeeds for a real library + (assert-true test + (Result.success? &(DynLib.open "libm.so.6")) + "open succeeds for libm") + + ; open fails for a nonexistent library + (assert-true test + (Result.error? &(DynLib.open "libnonexistent.so")) + "open fails for nonexistent library") + + ; get succeeds for a known symbol + (match (DynLib.open "libm.so.6") + (Result.Success lib) + (let-do [result (the (Result (Fn [Double] Double) String) + (DynLib.get lib "floor")) + ok (Result.success? &result)] + (ignore result) + (ignore (DynLib.close lib)) + (assert-true test ok "get succeeds for known symbol")) + (Result.Error _) (assert-true test false "get succeeds for known symbol")) + + ; get fails for a nonexistent symbol + (match (DynLib.open "libm.so.6") + (Result.Success lib) + (let-do [result (the (Result (Fn [] ()) String) + (DynLib.get lib "nonexistent_symbol_xyz")) + bad (Result.error? &result)] + (ignore result) + (ignore (DynLib.close lib)) + (assert-true test bad "get fails for nonexistent symbol")) + (Result.Error _) + (assert-true test false "get fails for nonexistent symbol")) + + ; close succeeds on a valid handle + (match (DynLib.open "libm.so.6") + (Result.Success lib) + (assert-true test + (Result.success? &(DynLib.close lib)) + "close succeeds on valid handle") + (Result.Error _) (assert-true test false "close succeeds on valid handle")) + + ; close returns Result.Success () on success + (match (DynLib.open "libm.so.6") + (Result.Success lib) + (assert-equal test + &(Result.Success ()) + &(DynLib.close lib) + "close returns Result.Success on success") + (Result.Error _) + (assert-true test false "close returns Result.Success on success"))))