limits/
limits.rs

1//! Finds various limits and default values for posix message queues.
2//! Used to find the values for one of the tables in the documentation.
3
4extern crate posixmq;
5
6/// binary search towards a limit
7fn btry<P:Fn(usize)->bool>(ceiling: usize,  ok: P) -> String {
8    let (mut min, mut max) = (0, ceiling);
9    while min < max {
10        let mid = max/2 + min/2;
11        //eprintln!("trying {:10} ({0:#010x})", mid);
12        if ok(mid) {
13            min = mid+1;
14        } else {
15            max = mid-1;
16        }
17    }
18    if !ok(min) {
19        min -= 1;
20    }
21    if min+1 >= ceiling {
22        "No limit".to_string()
23    } else {
24        min.to_string()
25    }
26}
27
28fn main() {
29    println!("{}:", std::env::consts::OS);
30
31    let mq = posixmq::OpenOptions::readwrite()
32        .create_new()
33        .open("/default_capacities")
34        .expect("Cannot create new posix message queue /default_capacities");
35    posixmq::remove_queue("/default_capacities")
36        .expect("Cannot delete posix message queue /default_capacities");
37
38    let attrs = mq.attributes().expect("Cannot get attributes for queue");
39    println!("default queue capacity:         {}", attrs.capacity);
40    println!("default maximum message length: {}", attrs.max_msg_len);
41
42    println!("max message priority:           {}", btry(0xff_ff_ff_ff, |priority| {
43        mq.send(priority as u32, b"b")
44            .map(|_| mq.recv(&mut vec![0; attrs.max_msg_len]).unwrap() )
45            .is_ok()
46    }));
47    println!("allows empty messages:          {}", mq.send(0, b"").is_ok());
48    drop(mq);
49
50    println!("max queue capacity:             {}", btry(1_000_000, |capacity| {
51        posixmq::OpenOptions::readwrite()
52            .capacity(capacity)
53            .max_msg_len(1)
54            .create_new()
55            .open("/max_capacity")
56            .map(|_| posixmq::remove_queue("/max_capacity").unwrap() )
57            .is_ok()
58    }));
59
60    println!("max message length:             {}", btry(1_000_000, |length| {
61        posixmq::OpenOptions::readwrite()
62            .max_msg_len(length)
63            .capacity(1)
64            .create_new()
65            .open("/max_length")
66            .map(|_| posixmq::remove_queue("/max_length").unwrap() )
67            .is_ok()
68    }));
69
70    println!("max equal:                      {}", btry(1_000_000, |equal| {
71        posixmq::OpenOptions::readwrite()
72            .max_msg_len(equal)
73            .capacity(equal)
74            .create_new()
75            .open("/max_equal")
76            .map(|_| posixmq::remove_queue("/max_equal").unwrap() )
77            .is_ok()
78    }));
79
80    println!("allows just \"/\":                {}", {
81        let result = posixmq::PosixMq::create("/");
82        let _ = posixmq::remove_queue("/");
83        result.is_ok()
84    });
85    println!("enforces name rules:            {}", {
86        let noslash = std::ffi::CStr::from_bytes_with_nul(b"noslash\0").unwrap();
87        let result = posixmq::OpenOptions::readwrite().create().open_c(noslash);
88        let _ = posixmq::remove_queue_c(noslash);
89        result.is_err()
90    });
91}