Skip to content

Unix: Add _PATH_BSHELL and _PATH_DEFPATH where available - #5449

Open
asder8215 wants to merge 1 commit into
rust-lang:mainfrom
asder8215:unix_paths_constants
Open

Unix: Add _PATH_BSHELL and _PATH_DEFPATH where available#5449
asder8215 wants to merge 1 commit into
rust-lang:mainfrom
asder8215:unix_paths_constants

Conversation

@asder8215

Copy link
Copy Markdown

This PR adds _PATH_BSHELL and _PATH_DEFPATH constants from include/paths.h on multiple unix-based platforms (a couple platforms only have _PATH_BSHELL). The reason for why we need these macros could be seen from this Zulip chat #t-libs/crates > Including <paths.h> macros into libc? @ 💬 and PR.

The following are sources to each platform's paths.h:

From BSD:

  • Apple: Has _PATH_BSHELL and _PATH_DEFPATH
  • Dragonfly: Has _PATH_BSHELL and _PATH_DEFPATH
  • FreeBSD: Has _PATH_BSHELL and _PATH_DEFPATH (verified same values on version 11+)
  • NetBSD: Has _PATH_BSHELL and _PATH_DEFPATH
  • OpenBSD: Has _PATH_BSHELL and _PATH_DEFPATH

From Linux:

  • Android: Has _PATH_BSHELL and _PATH_DEFPATH
  • glibc: Has _PATH_BSHELL and _PATH_DEFPATH
  • musl: Has _PATH_BSHELL and _PATH_DEFPATH
  • uClibc: Has _PATH_BSHELL and _PATH_DEFPATH
  • emscripten: Has _PATH_BSHELL and _PATH_DEFPATH
  • l4re: There's musl and uclibc paths.h file containing _PATH_BSHELL and _PATH_DEFPATH values

Miscellaneous Platforms:

  • Haiku: Has _PATH_BSHELL and _PATH_DEFPATH
  • Hurd: Doesn't have_PATH_BSHELL and _PATH_DEFPATH in paths.h (wouldn't hurt to confirm this though in terminal)
  • Cygwin: Has _PATH_BSHELL and _PATH_DEFPATH
  • newlib: Has _PATH_BSHELL
  • Redox: Has _PATH_BSHELL

Platforms I'm unsure if they have _PATH_BSHELL/_PATH_DEFPATH:

  • Solarish: I'm unsure how to get this info since I believe Solaris is closed source?
  • AIX: I think this is also closed source? However, I saw this archive repo of AIX 4.13 that has _PATH_BSHELL.
  • nuttx: Couldn't find a include/paths.h file.
  • NTO/QNX: Couldn't find a include/paths.h file.
    Would be helpful if someone could go on terminal and print out _PATH_BSHELL and see if that produces results?

Other questions I have are:

  • For NetBSD, I noticed that _PATH_DEFPATH concatenates the RESCUEDIR macro in front of its string literal if it exists, should we also have that in our _PATH_DEFPATH macro? I wasn't sure (I also don't know what the value of RESCUEDIR is), and I was advised by Jonas to reach out to @he32 and @0323pin since they're experienced with NetBSD.

This is also my first time contributing to libc. I've read through the CONTRIBUTING.md file and hopefully I got everything done correctly. I know the md file also mentions about reorganization effort for moving from the hierarchial structure to the source-mapped structure in src/new. If you want me to restructure the constants I'm introducing to src/new, I can try for that; I may need more clarity on how that process works.

cc @joboet
@rustbot label stable-nominated

@rustbot

rustbot commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in a NetBSD-like module

cc @semarie

Some changes occurred in an OpenBSD module

cc @semarie

Some changes occurred in an Android module

cc @maurer

@asder8215
asder8215 force-pushed the unix_paths_constants branch from 436cb4f to 03110d3 Compare August 31, 2026 01:15
@rustbot

rustbot commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@tgross35 tgross35 changed the title Added _PATH_BSHELL and _PATH_DEFPATH constants to multiple unix platforms Unix: Add _PATH_BSHELL and _PATH_DEFPATH where available Aug 31, 2026

@tgross35 tgross35 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You'll need to use byte arrays to meet the MSRV. Add a function to

libc/src/types.rs

Lines 69 to 140 in b6d2732

/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but
/// out-of-range for signed.
#[allow(unused)]
pub(crate) const fn u16_cast_short(x: u16) -> c_short {
assert!(size_of::<u16>() <= size_of::<c_short>()); // Should always be true
x as i16
}
/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but
/// out-of-range for signed.
#[allow(unused)]
pub(crate) const fn u32_cast_int(x: u32) -> c_int {
// May not be true on 16-bit platforms, but should be everywhere this is used.
assert!(size_of::<u32>() <= size_of::<c_int>());
x as i32
}
/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but
/// out-of-range for signed.
#[allow(unused)]
pub(crate) const fn u32_cast_long(x: u32) -> c_long {
assert!(size_of::<u32>() <= size_of::<c_long>()); // Should always be true
x as c_long
}
/// Checked casting from `unsigned long` to `int`.
#[allow(unused)]
pub(crate) const fn ulong_cast_int(x: c_ulong) -> c_int {
assert!(x <= (c_int::MAX as c_ulong));
x as c_int
}
/// Checked casting from `unsigned long` to `unsigned int`.
#[allow(unused)]
pub(crate) const fn ulong_cast_uint(x: c_ulong) -> c_uint {
assert!(x <= (c_uint::MAX as c_ulong));
x as c_uint
}
/// Used to avoid `overflowing_literals` when the value is in-range for the unsigned number but
/// out-of-range for signed.
#[allow(unused)]
#[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))]
pub(crate) const fn u32_cast_ioctl(x: u32) -> crate::Ioctl {
assert!(size_of::<u32>() <= size_of::<crate::Ioctl>()); // Should always be true
x as crate::Ioctl
}
#[allow(unused)]
pub(crate) const fn u8_slice_cast_char_slice(x: &[u8]) -> &[c_char] {
assert!(size_of::<u8>() == size_of::<c_char>());
// SAFETY: same repr, possibly just a sign cast
unsafe { mem::transmute::<&[u8], &[c_char]>(x) }
}
/// Replace bytes in an array with those from a slice. This is a polyfill for `[T]::copy_from_slice`
/// in `const`.
// FIXME(msrv): we can switch to `copy_from_slice` in 1.87.
#[must_use]
#[allow(dead_code)]
pub const fn replace_array_items<T: Copy, const N: usize>(
mut dst: [T; N],
src: &[T],
start: usize,
) -> [T; N] {
let mut i = 0;
while i < src.len() {
dst[i + start] = src[i];
i += 1;
}
dst
}
like fn cstr(bytes: &[u8]) -> *const c_char that asserts there's a single nul at the end and does the cast, with a FIXME(msrv) comment.

View changes since this review

Comment thread src/unix/bsd/apple/mod.rs
Comment on lines +4115 to +4116
/// Default search path
const _PATH_DEFPATH: *const c_char = c"/usr/bin:/bin".as_ptr();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Drop the doc comments, libc expects you to read the manpages

Comment on lines +1500 to +1515
// include/paths.h (Bionics libc paths.h: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/paths.h,
#[cfg(not(any(target_env = "musl", target_os = "android")))]
/// Default search path on glibc/uclibc Linux
pub const _PATH_DEFPATH: *const c_char = c"/usr/bin:/bin".as_ptr();
#[cfg(all(target_env = "musl", not(target_os = "android")))]
/// Default search path on musl Linux platforms
pub const _PATH_DEFPATH: *const c_char = c"/usr/local/bin:/bin:/usr/bin".as_ptr();
#[cfg(target_os = "android")]
/// Default search path on Android/Bionics libc
pub const _PATH_DEFPATH: *const c_char = c"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/apex/com.android.virt/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin".as_ptr();
/// Default shell path on Linux platforms (except Android)
#[cfg(not(target_os = "android"))]
pub const _PATH_BSHELL: *const c_char = c"/bin/sh".as_ptr();
/// Default shell path on Android
#[cfg(target_os = "android")]
pub const _PATH_BSHELL: *const c_char = c"/system/bin/sh".as_ptr();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Simplify this by using if cfg!(...) { ... } else { ... } rather than #[cfg]

pub const _PATH_DEFPATH: *const c_char = c"/usr/local/bin:/bin:/usr/bin".as_ptr();
#[cfg(target_os = "android")]
/// Default search path on Android/Bionics libc
pub const _PATH_DEFPATH: *const c_char = c"/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/apex/com.android.virt/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin".as_ptr();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please wrap long lines with \

@rustbot

rustbot commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@tgross35

Copy link
Copy Markdown
Member

Two other things:

  • Please add the source list to the commit message (this repo uses rebase merging)
  • You'll need to update libc-test/build.rs to include the relevant headers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants