libtz-sys 0.1.0

An FFI interface to IANA's timezone library, libtz [WIP, don't use yet]
libtz-sys
=========

Rust FFI interface for IANA's [libtz](https://www.iana.org/time-zones).

This provides an equivalent of glibc's `localtime_r()` function (and related
functions). The difference is that this library has been compiled such that the
`getenv("TZ")` call uses Rust's `std::env::var_os()` which protects it from
`std::env::set_var()` races which could otherwise cause segfaults.

Aside from that it should be a drop in replacement for glibc. It will read the
tzdata files that the system has installed to calculate things like leap seconds
and daylight saving time.

Usage
-----

Add this to your `Cargo.toml`:

```toml
[dependencies]
libtz-sys = "0.1.0"
```

Example
-------

```rust
use std::ffi::{CString,CStr};
use std::mem::MaybeUninit;
use libtz_sys::{tzalloc, localtime_rz, mktime_z, tzfree, TimeT, Tm};

let tzname = CString::new("America/New_York").unwrap();
let tz = unsafe { tzalloc(tzname.as_ptr()) };
if tz == std::ptr::null_mut() {
    return Err(std::io::Error::last_os_error());
}
let time: TimeT = 127810800;
let mut tm = MaybeUninit::<Tm>::uninit();
let ret = unsafe { localtime_rz(tz, &time, tm.as_mut_ptr()) };
if ret == std::ptr::null_mut() {
    return Err(std::io::Error::last_os_error());
}
let tm = unsafe { tm.assume_init() };
let zone: &str = unsafe { CStr::from_ptr(tm.tm_zone).to_str().expect("correct utf8") };
assert_eq!((tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mday, tm.tm_mon),
           (0,         0,         3,          19,         0,       ));
assert_eq!((tm.tm_year, tm.tm_wday, tm.tm_yday, tm.tm_isdst, tm.tm_gmtoff, zone),
           (74,         6,          18,         1,           -14400,       "EDT"));

let time_again = unsafe { mktime_z(tz, &tm) }; // Round trip
if time_again == -1 {
    // Didn't work (errno is not reliably set in this case)
} else {
    assert_eq!(time_again, time);
}
unsafe { tzfree(tz) };
# Ok(())
```

License
-------

The Rust code is distributed under the MIT license.

The libtz code is mostly public domain with a couple files using the BSD-3
clause license.

See [LICENSE.md](LICENSE.md) for details.