Skip to content

musl: 64-bit time support #4463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
8 changes: 8 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ jobs:
- target: loongarch64-unknown-linux-musl
env:
RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1
- target: arm-unknown-linux-musleabihf
env:
RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1
RUST_LIBC_UNSTABLE_MUSL_TIME64: 1
- target: i686-unknown-linux-musl
env:
RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1
RUST_LIBC_UNSTABLE_MUSL_TIME64: 1
# FIXME(ppc): SIGILL running tests, see
# https://github.com/rust-lang/libc/pull/4254#issuecomment-2636288713
# - target: powerpc-unknown-linux-gnu
Expand Down
18 changes: 16 additions & 2 deletions build.rs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think musl_time64 as it is used should be named something like musl_time64_on_32. We probably don't need an env to set this independently, build.rs should just set it when musl_time64 is set and target_ptr_width is 32.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I think I will rename it to something like musl_time64_on_32, musl32_time64 or maybe musl_redir_time64 as you suggested in the previous PR. I don't think there is a practical use for a separate musl_time64 variable.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const ALLOWED_CFGS: &[&str] = &[
// Corresponds to `__USE_TIME_BITS64` in UAPI
"linux_time_bits64",
"musl_v1_2_3",
"musl_time64",
"musl_not_time64",
];

// Extra values to allow for check-cfg.
Expand All @@ -44,6 +46,8 @@ const CHECK_CFG_EXTRA: &[(&str, &[&str])] = &[
),
];

const MUSL_TIME64_ARCHS: &[&str] = &["arm", "mips", "powerpc", "x86"];

fn main() {
// Avoid unnecessary re-building.
println!("cargo:rerun-if-changed=build.rs");
Expand Down Expand Up @@ -90,10 +94,20 @@ fn main() {

let musl_v1_2_3 = env::var("RUST_LIBC_UNSTABLE_MUSL_V1_2_3").is_ok();
println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_MUSL_V1_2_3");
let musl_time64 = env::var("RUST_LIBC_UNSTABLE_MUSL_TIME64").is_ok();
println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_MUSL_TIME64");
// loongarch64 and ohos have already updated
if musl_v1_2_3 || target_os == "loongarch64" || target_env == "ohos" {
// FIXME(musl): enable time64 api as well
if ((musl_v1_2_3 || target_os == "loongarch64") && target_env == "musl") || target_env == "ohos"
{
set_cfg("musl_v1_2_3");
if musl_time64 && MUSL_TIME64_ARCHS.contains(&target_arch.as_str()) {
set_cfg("musl_time64");
set_cfg("linux_time_bits64");
} else {
set_cfg("musl_not_time64");
}
} else if target_env == "musl" || target_env == "ohos" {
set_cfg("musl_not_time64");
Comment on lines +100 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is musl_not_time64 needed? not(musl_time64) should be usable everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is kind of a hack to ignore the deprecation warning for musl but not time64. I'll get rid of it by allowing deprecation for any not(musl_time64)

}
let linux_time_bits64 = env::var("RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64").is_ok();
println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64");
Expand Down
2 changes: 2 additions & 0 deletions ci/run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ run() {
--env LIBC_CI_ZBUILD_STD \
--env RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS \
--env RUST_LIBC_UNSTABLE_GNU_TIME_BITS \
--env RUST_LIBC_UNSTABLE_MUSL_V1_2_3 \
--env RUST_LIBC_UNSTABLE_MUSL_TIME64 \
--env CARGO_HOME=/cargo \
--env CARGO_TARGET_DIR=/checkout/target \
Comment on lines 46 to 51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this should match the indentation

--volume "$CARGO_HOME":/cargo \
Expand Down
9 changes: 9 additions & 0 deletions ci/verify-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ test_target() {
# Test with the equivalent of _TIME_BITS=64
RUST_LIBC_UNSTABLE_GNU_TIME_BITS=64 $cmd
;;
arm*-musl*|i*86-musl|powerpc-*-musl*|mips*-musl|thumb-*musl*)
# Test with new musl changes and the equivalent of _REDIR_TIME64
RUST_LIBC_UNSTABLE_MUSL_V1_2_3=1 \
RUST_LIBC_UNSTABLE_MUSL_TIME64=1 $cmd
;;
*musl*)
# Test with the new musl changes.
RUST_LIBC_UNSTABLE_MUSL_V1_2_3=1 $cmd
;;
esac
fi

Expand Down
18 changes: 16 additions & 2 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3683,14 +3683,22 @@ fn test_linux(target: &str) {
let loongarch64 = target.contains("loongarch64");
let wasm32 = target.contains("wasm32");
let uclibc = target.contains("uclibc");
let mips64 = target.contains("mips64");
let mips32 = target.contains("mips") && !mips64;

let musl_v1_2_3 = env::var("RUST_LIBC_UNSTABLE_MUSL_V1_2_3").is_ok();
let musl_time64 = env::var("RUST_LIBC_UNSTABLE_MUSL_TIME64").is_ok();
let old_musl = musl && !musl_v1_2_3;

let mut cfg = ctest_cfg();
if musl_v1_2_3 {
if (musl_v1_2_3 || loongarch64) && musl {
cfg.cfg("musl_v1_2_3", None);
if musl_time64 && (arm || ppc || x86_32 || mips32) {
cfg.cfg("musl_time64", None);
cfg.cfg("linux_time_bits64", None);
}
}

cfg.define("_GNU_SOURCE", None);
// This macro re-defines fscanf,scanf,sscanf to link to the symbols that are
// deprecated since glibc >= 2.29. This allows Rust binaries to link against
Expand Down Expand Up @@ -4299,6 +4307,10 @@ fn test_linux(target: &str) {
if old_musl && name == "RLIM_NLIMITS" {
return true;
}
// Incorrectly named and renamed upstream:
if old_musl && name == "SIGSTKFLT" {
return true;
}
}
match name {
// These constants are not available if gnu headers have been included
Expand Down Expand Up @@ -4872,7 +4884,9 @@ fn test_linux(target: &str) {
// the `xsk_tx_metadata_union` field is an anonymous union
(struct_ == "xsk_tx_metadata" && field == "xsk_tx_metadata_union") ||
// After musl 1.2.0, the type becomes `int` instead of `long`.
(old_musl && struct_ == "utmpx" && field == "ut_session")
(old_musl && struct_ == "utmpx" && field == "ut_session") ||
// FIXME(linux): this is changed to separate sec/usec fields when time64 is enabled
(struct_ == "input_event" && field == "time")
});

cfg.skip_roundtrip(move |s| match s {
Expand Down
16 changes: 16 additions & 0 deletions libc-test/semver/linux-powerpc-gnu.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
KEYCTL_CAPABILITIES
KEYCTL_CAPS0_BIG_KEY
KEYCTL_CAPS0_CAPABILITIES
KEYCTL_CAPS0_DIFFIE_HELLMAN
KEYCTL_CAPS0_INVALIDATE
KEYCTL_CAPS0_MOVE
KEYCTL_CAPS0_PERSISTENT_KEYRINGS
KEYCTL_CAPS0_PUBLIC_KEY
KEYCTL_CAPS0_RESTRICT_KEYRING
KEYCTL_CAPS1_NS_KEYRING_NAME
KEYCTL_CAPS1_NS_KEY_TAG
KEYCTL_MOVE
PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
sysctl
16 changes: 0 additions & 16 deletions libc-test/semver/linux-powerpc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,12 @@ B2500000
B3000000
B3500000
B4000000
KEYCTL_CAPABILITIES
KEYCTL_CAPS0_BIG_KEY
KEYCTL_CAPS0_CAPABILITIES
KEYCTL_CAPS0_DIFFIE_HELLMAN
KEYCTL_CAPS0_INVALIDATE
KEYCTL_CAPS0_MOVE
KEYCTL_CAPS0_PERSISTENT_KEYRINGS
KEYCTL_CAPS0_PUBLIC_KEY
KEYCTL_CAPS0_RESTRICT_KEYRING
KEYCTL_CAPS1_NS_KEYRING_NAME
KEYCTL_CAPS1_NS_KEY_TAG
KEYCTL_MOVE
MADV_SOFT_OFFLINE
MAP_SYNC
NFT_MSG_DELOBJ
NFT_MSG_GETOBJ
NFT_MSG_GETOBJ_RESET
NFT_MSG_NEWOBJ
PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
PTRACE_GETFPREGS
PTRACE_GETREGS
PTRACE_SETFPREGS
Expand Down Expand Up @@ -158,4 +143,3 @@ TIOCSRS485
flock64
fsblkcnt64_t
fsfilcnt64_t
sysctl
39 changes: 31 additions & 8 deletions src/unix/linux_like/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2850,8 +2850,14 @@ pub const IPC_NOWAIT: c_int = 0o4000;

pub const IPC_RMID: c_int = 0;
pub const IPC_SET: c_int = 1;
#[cfg(musl_time64)]
pub const IPC_STAT: c_int = 0x102;
#[cfg(not(musl_time64))]
pub const IPC_STAT: c_int = 2;
Comment on lines +2853 to 2856
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit: these should be writeable as pub const IPC_STAT: c_int = if cfg!(musl_time64) { 0x102 } else { 2 } to get the else fallback and reduce the amount of code that is cfged out on some platforms.

pub const IPC_INFO: c_int = 3;
#[cfg(musl_time64)]
pub const MSG_STAT: c_int = 0x10b;
#[cfg(not(musl_time64))]
pub const MSG_STAT: c_int = 11;
pub const MSG_INFO: c_int = 12;
pub const MSG_NOTIFICATION: c_int = 0x8000;
Expand All @@ -2869,8 +2875,14 @@ pub const GETNCNT: c_int = 14;
pub const GETZCNT: c_int = 15;
pub const SETVAL: c_int = 16;
pub const SETALL: c_int = 17;
#[cfg(musl_time64)]
pub const SEM_STAT: c_int = 0x112;
#[cfg(not(musl_time64))]
pub const SEM_STAT: c_int = 18;
pub const SEM_INFO: c_int = 19;
#[cfg(musl_time64)]
pub const SEM_STAT_ANY: c_int = 0x114;
#[cfg(not(musl_time64))]
pub const SEM_STAT_ANY: c_int = 20;

pub const SHM_R: c_int = 0o400;
Expand Down Expand Up @@ -6107,7 +6119,7 @@ cfg_if! {
pub fn aio_error(aiocbp: *const aiocb) -> c_int;
#[cfg_attr(gnu_file_offset_bits64, link_name = "aio_return64")]
pub fn aio_return(aiocbp: *mut aiocb) -> ssize_t;
#[cfg_attr(gnu_time_bits64, link_name = "__aio_suspend_time64")]
#[cfg_attr(any(musl_time64, gnu_time_bits64), link_name = "__aio_suspend_time64")]
pub fn aio_suspend(
aiocb_list: *const *const aiocb,
nitems: c_int,
Expand Down Expand Up @@ -6170,6 +6182,7 @@ cfg_if! {
flags: c_ulong,
) -> isize;
#[cfg_attr(gnu_time_bits64, link_name = "__futimes64")]
#[cfg_attr(musl_time64, link_name = "__futimes_time64")]
pub fn futimes(fd: c_int, times: *const crate::timeval) -> c_int;
}
}
Expand Down Expand Up @@ -6199,7 +6212,7 @@ cfg_if! {
msg_len: size_t,
msg_prio: *mut c_uint,
) -> ssize_t;
#[cfg_attr(gnu_time_bits64, link_name = "__mq_timedreceive_time64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__mq_timedreceive_time64")]
pub fn mq_timedreceive(
mqd: crate::mqd_t,
msg_ptr: *mut c_char,
Expand All @@ -6213,7 +6226,7 @@ cfg_if! {
msg_len: size_t,
msg_prio: c_uint,
) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__mq_timedsend_time64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__mq_timedsend_time64")]
pub fn mq_timedsend(
mqd: crate::mqd_t,
msg_ptr: *const c_char,
Expand Down Expand Up @@ -6265,6 +6278,7 @@ extern "C" {
pub fn lcong48(p: *mut c_ushort);

#[cfg_attr(gnu_time_bits64, link_name = "__lutimes64")]
#[cfg_attr(musl_time64, link_name = "__lutimes_time64")]
pub fn lutimes(file: *const c_char, times: *const crate::timeval) -> c_int;

pub fn setpwent();
Expand Down Expand Up @@ -6360,9 +6374,9 @@ extern "C" {
pub fn fremovexattr(filedes: c_int, name: *const c_char) -> c_int;
pub fn signalfd(fd: c_int, mask: *const crate::sigset_t, flags: c_int) -> c_int;
pub fn timerfd_create(clockid: crate::clockid_t, flags: c_int) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__timerfd_gettime64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__timerfd_gettime64")]
pub fn timerfd_gettime(fd: c_int, curr_value: *mut itimerspec) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__timerfd_settime64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__timerfd_settime64")]
pub fn timerfd_settime(
fd: c_int,
flags: c_int,
Expand All @@ -6379,6 +6393,7 @@ extern "C" {
) -> c_int;
pub fn dup3(oldfd: c_int, newfd: c_int, flags: c_int) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__sigtimedwait64")]
#[cfg_attr(musl_time64, link_name = "__sigtimedwait_time64")]
pub fn sigtimedwait(
set: *const sigset_t,
info: *mut siginfo_t,
Expand Down Expand Up @@ -6499,6 +6514,7 @@ extern "C" {
pub fn sched_get_priority_max(policy: c_int) -> c_int;
pub fn tee(fd_in: c_int, fd_out: c_int, len: size_t, flags: c_uint) -> ssize_t;
#[cfg_attr(gnu_time_bits64, link_name = "__settimeofday64")]
#[cfg_attr(musl_time64, link_name = "__settimeofday_time64")]
pub fn settimeofday(tv: *const crate::timeval, tz: *const crate::timezone) -> c_int;
pub fn splice(
fd_in: c_int,
Expand All @@ -6513,8 +6529,10 @@ extern "C" {
pub fn eventfd_write(fd: c_int, value: eventfd_t) -> c_int;

#[cfg_attr(gnu_time_bits64, link_name = "__sched_rr_get_interval64")]
#[cfg_attr(musl_time64, link_name = "__sched_rr_get_interval_time64")]
pub fn sched_rr_get_interval(pid: crate::pid_t, tp: *mut crate::timespec) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__sem_timedwait64")]
#[cfg_attr(musl_time64, link_name = "__sem_timedwait_time64")]
pub fn sem_timedwait(sem: *mut sem_t, abstime: *const crate::timespec) -> c_int;
pub fn sem_getvalue(sem: *mut sem_t, sval: *mut c_int) -> c_int;
pub fn sched_setparam(pid: crate::pid_t, param: *const crate::sched_param) -> c_int;
Expand All @@ -6534,6 +6552,7 @@ extern "C" {
pub fn prctl(option: c_int, ...) -> c_int;
pub fn sched_getparam(pid: crate::pid_t, param: *mut crate::sched_param) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__ppoll64")]
#[cfg_attr(musl_time64, link_name = "__ppoll_time64")]
pub fn ppoll(
fds: *mut crate::pollfd,
nfds: nfds_t,
Expand All @@ -6547,6 +6566,7 @@ extern "C" {
pub fn pthread_mutexattr_setprotocol(attr: *mut pthread_mutexattr_t, protocol: c_int) -> c_int;

#[cfg_attr(gnu_time_bits64, link_name = "__pthread_mutex_timedlock64")]
#[cfg_attr(musl_time64, link_name = "__pthread_mutex_timedlock_time64")]
pub fn pthread_mutex_timedlock(
lock: *mut pthread_mutex_t,
abstime: *const crate::timespec,
Expand Down Expand Up @@ -6581,7 +6601,10 @@ extern "C" {
...
) -> c_int;
pub fn sched_getscheduler(pid: crate::pid_t) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__clock_nanosleep_time64")]
#[cfg_attr(
any(gnu_time_bits64, musl_time64),
link_name = "__clock_nanosleep_time64"
)]
pub fn clock_nanosleep(
clk_id: crate::clockid_t,
flags: c_int,
Expand Down Expand Up @@ -6839,9 +6862,9 @@ extern "C" {
) -> c_int;
pub fn timer_delete(timerid: crate::timer_t) -> c_int;
pub fn timer_getoverrun(timerid: crate::timer_t) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__timer_gettime64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__timer_gettime64")]
pub fn timer_gettime(timerid: crate::timer_t, curr_value: *mut crate::itimerspec) -> c_int;
#[cfg_attr(gnu_time_bits64, link_name = "__timer_settime64")]
#[cfg_attr(any(gnu_time_bits64, musl_time64), link_name = "__timer_settime64")]
pub fn timer_settime(
timerid: crate::timer_t,
flags: c_int,
Expand Down
Loading
Loading