extrasafe 0.1.2

Make your code extrasafe by preventing it from calling unneeded syscalls.
Documentation
use extrasafe::builtins::SystemIO;

use std::sync::mpsc::sync_channel;
use std::thread;

use std::fs::File;

#[test]
/// Test TSYNC behavior by enabling on one thread and failing IO on another.
fn sync_thread_contexts() {
    let dir = tempfile::tempdir().unwrap();

    // These channels will block on send until the receiver has called recv.
    let (sender1, recv1) = sync_channel::<()>(0);
    let (sender2, recv2) = sync_channel::<()>(0);

    let seccomp_thread = thread::spawn(move || {
        extrasafe::SafetyContext::new()
            .enable(SystemIO::nothing()
                .allow_stdout()
                .allow_stderr()).unwrap()
            .apply_to_all_threads().unwrap();
        // setup_done
        sender1.send(()).unwrap();

        // don't close this thread until the other thread is done asserting. This way we can be
        // sure the thread that loaded the filter is definitely active when the other thread runs.
        let _io_test_passed = recv2.recv().unwrap();
        println!("exit seccomp thread");
    });

    let io_thread = thread::spawn(move || {
        let _setup_done = recv1.recv().unwrap();

        let mut path = dir.path().to_path_buf();
        path.push("can_open.txt");

        let res = File::create(&path);
        assert!(
            res.is_err(),
            "Incorrectly succeeded in opening file after seccomp was loaded on other thread"
        );

        // io_test_passed
        sender2.send(()).unwrap();
        println!("exit io thread");
    });

    let seccomp_res = seccomp_thread.join();
    assert!(
        seccomp_res.is_ok(),
        "seccomp thread failed: {:?}",
        seccomp_res.unwrap_err()
    );
    let io_res = io_thread.join();
    assert!(
        io_res.is_ok(),
        "io thread failed: {:?}",
        io_res.unwrap_err()
    );
}