Add more Cygwin support (#9686)

* GNUMakefile: add support for cygwin

* uucore: add more cygwin support

* chroot, id, nohup, stdbuf, stty: add support for cygwin

* uucore, chroot, id, nohup, stdbuf: format

* chore: format

* chore: fix spelling

* GNUMakefile: fix inverted check
This commit is contained in:
500-internal-server-error
2025-12-24 05:36:09 +07:00
committed by GitHub
parent 949f038b3b
commit 54ba74bb7e
10 changed files with 165 additions and 18 deletions
+9 -5
View File
@@ -62,15 +62,15 @@ TOYBOX_SRC := $(TOYBOX_ROOT)/toybox-$(TOYBOX_VER)
#------------------------------------------------------------------------
# Detect the host system.
# On Windows the environment already sets OS = Windows_NT.
# On Windows uname -s might return MINGW_NT-* or CYGWIN_NT-*.
# Otherwise let it default to the kernel name returned by uname -s
# (Linux, Darwin, FreeBSD, …).
#------------------------------------------------------------------------
OS ?= $(shell uname -s)
OS := $(shell uname -s)
# Windows does not allow symlink by default.
# Allow to override LN for AppArmor.
ifeq ($(OS),Windows_NT)
ifneq (,$(findstring _NT,$(OS)))
LN ?= ln -f
endif
LN ?= ln -sf
@@ -195,7 +195,7 @@ HASHSUM_PROGS := \
$(info Detected OS = $(OS))
ifneq ($(OS),Windows_NT)
ifeq (,$(findstring MINGW,$(OS)))
PROGS += $(UNIX_PROGS)
endif
ifeq ($(SELINUX_ENABLED),1)
@@ -450,8 +450,12 @@ install: build install-manpages install-completions install-locales
mkdir -p $(INSTALLDIR_BIN)
ifneq (,$(and $(findstring stdbuf,$(UTILS)),$(findstring feat_external_libstdbuf,$(CARGOFLAGS))))
mkdir -p $(DESTDIR)$(LIBSTDBUF_DIR)
ifneq (,$(findstring CYGWIN,$(OS)))
$(INSTALL) -m 755 $(BUILDDIR)/deps/stdbuf.dll $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf.dll
else
$(INSTALL) -m 755 $(BUILDDIR)/deps/libstdbuf.* $(DESTDIR)$(LIBSTDBUF_DIR)/
endif
endif
ifeq (${MULTICALL}, y)
$(INSTALL) -m 755 $(BUILDDIR)/coreutils $(INSTALLDIR_BIN)/$(PROG_PREFIX)coreutils
$(foreach prog, $(filter-out coreutils, $(INSTALLEES)), \
@@ -472,7 +476,7 @@ else
endif
uninstall:
ifneq ($(OS),Windows_NT)
ifeq (,$(findstring MINGW,$(OS)))
rm -f $(DESTDIR)$(LIBSTDBUF_DIR)/libstdbuf.*
-rm -d $(DESTDIR)$(LIBSTDBUF_DIR) 2>/dev/null || true
endif
+6 -1
View File
@@ -319,7 +319,12 @@ fn supplemental_gids(uid: libc::uid_t) -> Vec<libc::gid_t> {
/// Set the supplemental group IDs for this process.
fn set_supplemental_gids(gids: &[libc::gid_t]) -> std::io::Result<()> {
#[cfg(any(target_vendor = "apple", target_os = "freebsd", target_os = "openbsd"))]
#[cfg(any(
target_vendor = "apple",
target_os = "freebsd",
target_os = "openbsd",
target_os = "cygwin"
))]
let n = gids.len() as libc::c_int;
#[cfg(any(target_os = "linux", target_os = "android"))]
let n = gids.len() as libc::size_t;
+18 -3
View File
@@ -535,7 +535,12 @@ fn pline(possible_uid: Option<uid_t>) {
);
}
#[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "openbsd",
target_os = "cygwin"
))]
fn pline(possible_uid: Option<uid_t>) {
let uid = possible_uid.unwrap_or_else(getuid);
let pw = Passwd::locate(uid).unwrap();
@@ -552,10 +557,20 @@ fn pline(possible_uid: Option<uid_t>) {
);
}
#[cfg(any(target_os = "linux", target_os = "android", target_os = "openbsd"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "openbsd",
target_os = "cygwin"
))]
fn auditid() {}
#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "openbsd")))]
#[cfg(not(any(
target_os = "linux",
target_os = "android",
target_os = "openbsd",
target_os = "cygwin"
)))]
fn auditid() {
use std::mem::MaybeUninit;
+2 -1
View File
@@ -185,7 +185,8 @@ unsafe extern "C" {
target_os = "linux",
target_os = "android",
target_os = "freebsd",
target_os = "openbsd"
target_os = "openbsd",
target_os = "cygwin"
))]
/// # Safety
/// This function is unsafe because it dereferences a raw pointer.
+8
View File
@@ -26,6 +26,11 @@ mod platform {
pub const DYLIB_EXT: &str = ".dylib";
}
#[cfg(target_os = "cygwin")]
mod platform {
pub const DYLIB_EXT: &str = ".dll";
}
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/libstdbuf/src/libstdbuf.rs");
@@ -103,6 +108,9 @@ fn main() {
assert!(status.success(), "Failed to build libstdbuf");
// Copy the built library to OUT_DIR for include_bytes! to find
#[cfg(target_os = "cygwin")]
let lib_name = format!("stdbuf{}", platform::DYLIB_EXT);
#[cfg(not(target_os = "cygwin"))]
let lib_name = format!("libstdbuf{}", platform::DYLIB_EXT);
let dest_path = Path::new(&out_dir).join(format!("libstdbuf{}", platform::DYLIB_EXT));
+2 -2
View File
@@ -11,8 +11,8 @@ fn main() {
println!("cargo:rustc-link-arg=-fPIC");
let target = env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
// Ensure the library doesn't have any undefined symbols (-z flag not supported on macOS)
if !target.contains("apple-darwin") {
// Ensure the library doesn't have any undefined symbols (-z flag not supported on macOS and Cygwin)
if !target.contains("apple-darwin") && !target.contains("cygwin") {
println!("cargo:rustc-link-arg=-z");
println!("cargo:rustc-link-arg=defs");
}
+88 -4
View File
@@ -2,7 +2,7 @@
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
// spell-checker:ignore (ToDO) IOFBF IOLBF IONBF setvbuf stderrp stdinp stdoutp
// spell-checker:ignore (ToDO) getreent reent IOFBF IOLBF IONBF setvbuf stderrp stdinp stdoutp
use ctor::ctor;
use libc::{_IOFBF, _IOLBF, _IONBF, FILE, c_char, c_int, fileno, size_t};
@@ -35,7 +35,35 @@ pub unsafe extern "C" fn __stdbuf_get_stdin() -> *mut FILE {
unsafe { __stdin }
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
#[cfg(target_os = "cygwin")]
{
// _getreent()->_std{in,out,err}
// see:
// echo '#include <stdio.h>\nstd{in,out,err}' | gcc -E -xc - -std=c23 | tail -n1
// echo '#include <stdio.h>' | grep -E -xc - -std=c23 | grep 'struct _reent' -A91 | grep 580 -A91 | tail -n+2
#[repr(C)]
struct _reent {
_errno: c_int,
_stdin: *mut FILE,
_stdout: *mut FILE,
_stderr: *mut FILE,
// other stuff
}
unsafe extern "C" {
fn __getreent() -> *mut _reent;
}
unsafe { (*__getreent())._stdin }
}
#[cfg(not(any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "cygwin"
)))]
{
unsafe extern "C" {
static mut stdin: *mut FILE;
@@ -64,7 +92,35 @@ pub unsafe extern "C" fn __stdbuf_get_stdout() -> *mut FILE {
unsafe { __stdout }
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
#[cfg(target_os = "cygwin")]
{
// _getreent()->_std{in,out,err}
// see:
// echo '#include <stdio.h>\nstd{in,out,err}' | gcc -E -xc - -std=c23 | tail -n1
// echo '#include <stdio.h>' | grep -E -xc - -std=c23 | grep 'struct _reent' -A91 | grep 580 -A91 | tail -n+2
#[repr(C)]
struct _reent {
_errno: c_int,
_stdin: *mut FILE,
_stdout: *mut FILE,
_stderr: *mut FILE,
// other stuff
}
unsafe extern "C" {
fn __getreent() -> *mut _reent;
}
unsafe { (*__getreent())._stdout }
}
#[cfg(not(any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "cygwin"
)))]
{
unsafe extern "C" {
static mut stdout: *mut FILE;
@@ -93,7 +149,35 @@ pub unsafe extern "C" fn __stdbuf_get_stderr() -> *mut FILE {
unsafe { __stderr }
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))]
#[cfg(target_os = "cygwin")]
{
// _getreent()->_std{in,out,err}
// see:
// echo '#include <stdio.h>\nstd{in,out,err}' | gcc -E -xc - -std=c23 | tail -n1
// echo '#include <stdio.h>' | grep -E -xc - -std=c23 | grep 'struct _reent' -A91 | grep 580 -A91 | tail -n+2
#[repr(C)]
struct _reent {
_errno: c_int,
_stdin: *mut FILE,
_stdout: *mut FILE,
_stderr: *mut FILE,
// other stuff
}
unsafe extern "C" {
fn __getreent() -> *mut _reent;
}
unsafe { (*__getreent())._stdin }
}
#[cfg(not(any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "cygwin"
)))]
{
unsafe extern "C" {
static mut stderr: *mut FILE;
+3
View File
@@ -43,6 +43,9 @@ const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf
#[cfg(all(not(feature = "feat_external_libstdbuf"), target_vendor = "apple"))]
const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf.dylib"));
#[cfg(all(not(feature = "feat_external_libstdbuf"), target_os = "cygwin"))]
const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf.dll"));
enum BufferType {
Default,
Line,
+3
View File
@@ -256,13 +256,16 @@ pub const LOCAL_FLAGS: &[Flag<L>] = &[
// Not supported by nix
// Flag::new("xcase", L::XCASE),
Flag::new("tostop", L::TOSTOP),
#[cfg(not(target_os = "cygwin"))]
Flag::new("echoprt", L::ECHOPRT),
#[cfg(not(target_os = "cygwin"))]
Flag::new("prterase", L::ECHOPRT).hidden(),
Flag::new("echoctl", L::ECHOCTL).sane(),
Flag::new("ctlecho", L::ECHOCTL).sane().hidden(),
Flag::new("echoke", L::ECHOKE).sane(),
Flag::new("crtkill", L::ECHOKE).sane().hidden(),
Flag::new("flusho", L::FLUSHO),
#[cfg(not(target_os = "cygwin"))]
Flag::new("extproc", L::EXTPROC),
];
+26 -2
View File
@@ -3,7 +3,7 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
//
// spell-checker:ignore logind
// spell-checker:ignore IDLEN logind
//! Aims to provide platform-independent methods to obtain login records
//!
@@ -56,7 +56,12 @@ pub use libc::getutxent;
#[cfg_attr(target_env = "musl", allow(deprecated))]
pub use libc::setutxent;
use libc::utmpx;
#[cfg(any(target_vendor = "apple", target_os = "linux", target_os = "netbsd"))]
#[cfg(any(
target_vendor = "apple",
target_os = "linux",
target_os = "netbsd",
target_os = "cygwin"
))]
#[cfg_attr(target_env = "musl", allow(deprecated))]
pub use libc::utmpxname;
@@ -179,6 +184,25 @@ mod ut {
pub use libc::USER_PROCESS;
}
#[cfg(target_os = "cygwin")]
mod ut {
pub static DEFAULT_FILE: &str = "";
pub use libc::UT_HOSTSIZE;
pub use libc::UT_IDLEN;
pub use libc::UT_LINESIZE;
pub use libc::UT_NAMESIZE;
pub use libc::BOOT_TIME;
pub use libc::DEAD_PROCESS;
pub use libc::INIT_PROCESS;
pub use libc::LOGIN_PROCESS;
pub use libc::NEW_TIME;
pub use libc::OLD_TIME;
pub use libc::RUN_LVL;
pub use libc::USER_PROCESS;
}
/// A login record
pub struct Utmpx {
inner: utmpx,