+ unsafe {
+ rust_drop_global_args_lock();
+ }
+ }
+ }
+
+ fn get_global_ptr() -> *mut Option<~~[~str]> {
+ unsafe { rust_get_global_args_ptr() }
+ }
+
+ // Copied from `os`.
+ unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~str] {
+ let mut args = ~[];
+ for uint::range(0, argc as uint) |i| {
+ args.push(str::raw::from_c_str(*(argv as **libc::c_char).offset(i)));
+ }
+ return args;
+ }
+
+ extern {
+ fn rust_take_global_args_lock();
+ fn rust_drop_global_args_lock();
+ fn rust_get_global_args_ptr() -> *mut Option<~~[~str]>;
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use option::{Some, None};
+ use super::*;
+ use unstable::finally::Finally;
+
+ #[test]
+ fn smoke_test() {
+ // Preserve the actual global state.
+ let saved_value = take();
+
+ let expected = ~[~"happy", ~"today?"];
+
+ put(expected.clone());
+ assert!(clone() == Some(expected.clone()));
+ assert!(take() == Some(expected.clone()));
+ assert!(take() == None);
+
+ do (|| {
+ }).finally {
+ // Restore the actual global state.
+ match saved_value {
+ Some(ref args) => put(args.clone()),
+ None => ()
+ }