fix: rebase base patches, commit recipe drift, add relibc rlimit/sysconf
Base: fix P6-driver-new-modules.patch (ed format -> unified diff) for new driver modules (ncq, itr, phy). P6-driver-main-fixes.patch now applies with offset on current upstream source. Relibc: remove stale P5-named-semaphores (upstream has stubs), add P10-stack-size-8mb and P11-getrlimit-getrusage (per-process rlimit table, sysconf integration, getdtablesize fix, null-pointer safety). Kernel: consolidate 29 individual patches into single redbear-consolidated.patch. Userutils: P5-redbear-branding replaces P4-login-rate-limit. Recipe.toml changes now committed so they survive source resets.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs
|
||||
index 31a2add7..a75a0a35 100755
|
||||
--- a/drivers/audio/ihdad/src/main.rs
|
||||
+++ b/drivers/audio/ihdad/src/main.rs
|
||||
@@ -57,7 +57,15 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
EventQueue::<Source>::new().expect("ihdad: Could not create event queue.");
|
||||
let socket = Socket::nonblock().expect("ihdad: failed to create socket");
|
||||
let mut device = unsafe {
|
||||
- hda::IntelHDA::new(address, vend_prod).expect("ihdad: failed to allocate device")
|
||||
+ match hda::IntelHDA::new(address, vend_prod) {
|
||||
+ Ok(dev) => dev,
|
||||
+ Err(e) => {
|
||||
+ log::error!("ihdad: failed to initialize HDA device (err {}), exiting gracefully", e);
|
||||
+ log::info!("ihdad: this is expected in virtual environments without functional HDA hardware");
|
||||
+ daemon.ready();
|
||||
+ return loop {};
|
||||
+ }
|
||||
+ }
|
||||
};
|
||||
let mut readiness_based = ReadinessBased::new(&socket, 16);
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs
|
||||
index ffa8a94b..29e189be 100644
|
||||
--- a/drivers/audio/ac97d/src/main.rs
|
||||
+++ b/drivers/audio/ac97d/src/main.rs
|
||||
@@ -63,14 +63,14 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("ac97d: subscribe IRQ failed");
|
||||
event_queue
|
||||
.subscribe(
|
||||
socket.inner().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("ac97d: subscribe scheme failed");
|
||||
|
||||
register_sync_scheme(&socket, "audiohw", &mut device)
|
||||
.expect("ac97d: failed to register audiohw scheme to namespace");
|
||||
@@ -86,12 +86,12 @@ fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! {
|
||||
match event {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
- irq_file.read(&mut irq).unwrap();
|
||||
+ irq_file.read(&mut irq).expect("ac97d: IRQ read failed");
|
||||
|
||||
if !device.irq() {
|
||||
continue;
|
||||
}
|
||||
- irq_file.write(&mut irq).unwrap();
|
||||
+ irq_file.write(&mut irq).expect("ac97d: IRQ ack failed");
|
||||
|
||||
readiness_based
|
||||
.poll_all_requests(&mut device)
|
||||
diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs
|
||||
index 31a2add7..8291a550 100755
|
||||
--- a/drivers/audio/ihdad/src/main.rs
|
||||
+++ b/drivers/audio/ihdad/src/main.rs
|
||||
@@ -71,14 +71,14 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("ihdad: subscribe scheme failed");
|
||||
event_queue
|
||||
.subscribe(
|
||||
irq_file.irq_handle().as_raw_fd() as usize,
|
||||
Source::Irq,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("ihdad: subscribe IRQ failed");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("ihdad: failed to enter null namespace");
|
||||
|
||||
@@ -91,12 +91,12 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
match event {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
- irq_file.irq_handle().read(&mut irq).unwrap();
|
||||
+ irq_file.irq_handle().read(&mut irq).expect("ihdad: IRQ read failed");
|
||||
|
||||
if !device.irq() {
|
||||
continue;
|
||||
}
|
||||
- irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
+ irq_file.irq_handle().write(&mut irq).expect("ihdad: IRQ ack failed");
|
||||
|
||||
readiness_based
|
||||
.poll_all_requests(&mut device)
|
||||
diff --git a/drivers/net/e1000d/src/main.rs b/drivers/net/e1000d/src/main.rs
|
||||
index 373ea9b3..c66cccd1 100644
|
||||
--- a/drivers/net/e1000d/src/main.rs
|
||||
+++ b/drivers/net/e1000d/src/main.rs
|
||||
@@ -70,15 +70,15 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
|
||||
libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace");
|
||||
|
||||
- scheme.tick().unwrap();
|
||||
+ scheme.tick().expect("e1000d: tick failed");
|
||||
|
||||
for event in event_queue.map(|e| e.expect("e1000d: failed to get event")) {
|
||||
match event.user_data {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
- irq_file.read(&mut irq).unwrap();
|
||||
+ irq_file.read(&mut irq).expect("e1000d: IRQ read failed");
|
||||
if unsafe { scheme.adapter().irq() } {
|
||||
- irq_file.write(&mut irq).unwrap();
|
||||
+ irq_file.write(&mut irq).expect("e1000d: IRQ ack failed");
|
||||
|
||||
scheme.tick().expect("e1000d: failed to handle IRQ")
|
||||
}
|
||||
diff --git a/drivers/net/rtl8168d/src/main.rs b/drivers/net/rtl8168d/src/main.rs
|
||||
index 1d9963a3..5dc244af 100644
|
||||
--- a/drivers/net/rtl8168d/src/main.rs
|
||||
+++ b/drivers/net/rtl8168d/src/main.rs
|
||||
@@ -81,33 +81,33 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
Source::Irq,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("rtl8168d: subscribe IRQ failed");
|
||||
event_queue
|
||||
.subscribe(
|
||||
scheme.event_handle().raw(),
|
||||
Source::Scheme,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
- .unwrap();
|
||||
+ .expect("rtl8168d: subscribe scheme failed");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("rtl8168d: failed to enter null namespace");
|
||||
|
||||
- scheme.tick().unwrap();
|
||||
+ scheme.tick().expect("rtl8168d: tick failed");
|
||||
|
||||
for event in event_queue.map(|e| e.expect("rtl8168d: failed to get next event")) {
|
||||
match event.user_data {
|
||||
Source::Irq => {
|
||||
let mut irq = [0; 8];
|
||||
- irq_file.irq_handle().read(&mut irq).unwrap();
|
||||
+ irq_file.irq_handle().read(&mut irq).expect("rtl8168d: IRQ read failed");
|
||||
//TODO: This may be causing spurious interrupts
|
||||
if unsafe { scheme.adapter_mut().irq() } {
|
||||
- irq_file.irq_handle().write(&mut irq).unwrap();
|
||||
+ irq_file.irq_handle().write(&mut irq).expect("rtl8168d: IRQ ack failed");
|
||||
|
||||
- scheme.tick().unwrap();
|
||||
+ scheme.tick().expect("rtl8168d: tick failed");
|
||||
}
|
||||
}
|
||||
Source::Scheme => {
|
||||
- scheme.tick().unwrap();
|
||||
+ scheme.tick().expect("rtl8168d: tick failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/drivers/storage/ahcid/src/main.rs b/drivers/storage/ahcid/src/main.rs
|
||||
index 1f130a29..9a0e3e0d 100644
|
||||
--- a/drivers/storage/ahcid/src/main.rs
|
||||
+++ b/drivers/storage/ahcid/src/main.rs
|
||||
@@ -66,17 +66,17 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
.expect("ahcid: failed to event scheme socket");
|
||||
event_queue
|
||||
.subscribe(irq_fd, 1, EventFlags::READ)
|
||||
- .expect("ahcid: failed to event irq scheme");
|
||||
+ .expect("ahcid: IRQ failed");
|
||||
|
||||
for event in event_queue {
|
||||
- let event = event.unwrap();
|
||||
+ let event = event.expect("ahcid: event failed");
|
||||
if event.fd == scheme.event_handle().raw() {
|
||||
- FuturesExecutor.block_on(scheme.tick()).unwrap();
|
||||
+ FuturesExecutor.block_on(scheme.tick()).expect("ahcid: tick failed");
|
||||
} else if event.fd == irq_fd {
|
||||
let mut irq = [0; 8];
|
||||
if irq_file
|
||||
.read(&mut irq)
|
||||
- .expect("ahcid: failed to read irq file")
|
||||
+ .expect("ahcid: IRQ failed")
|
||||
>= irq.len()
|
||||
{
|
||||
let is = hba_mem.is.read();
|
||||
@@ -94,9 +94,9 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
|
||||
|
||||
irq_file
|
||||
.write(&irq)
|
||||
- .expect("ahcid: failed to write irq file");
|
||||
+ .expect("ahcid: IRQ failed");
|
||||
|
||||
- FuturesExecutor.block_on(scheme.tick()).unwrap();
|
||||
+ FuturesExecutor.block_on(scheme.tick()).expect("ahcid: tick failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -0,0 +1,193 @@
|
||||
diff --git a/drivers/net/e1000d/src/itr.rs b/drivers/net/e1000d/src/itr.rs
|
||||
new file mode 100644
|
||||
index 00000000..a0d79a5f
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/e1000d/src/itr.rs
|
||||
@@ -0,0 +1,61 @@
|
||||
+use crate::device::Intel8254x;
|
||||
+
|
||||
+pub const ITR_IMMEDIATE: u32 = 0;
|
||||
+pub const ITR_LOW_LATENCY: u32 = 64;
|
||||
+pub const ITR_BULK: u32 = 256;
|
||||
+pub const ITR_DEFAULT: u32 = 800;
|
||||
+
|
||||
+#[derive(Clone, Copy, PartialEq)]
|
||||
+pub enum ItrState { LowLatency, Moderate, Bulk }
|
||||
+
|
||||
+pub struct ItrTracker {
|
||||
+ state: ItrState,
|
||||
+ current_itr: u32,
|
||||
+ packets_since_update: u32,
|
||||
+}
|
||||
+
|
||||
+impl ItrTracker {
|
||||
+ pub const fn new() -> Self {
|
||||
+ Self { state: ItrState::LowLatency, current_itr: ITR_LOW_LATENCY, packets_since_update: 0 }
|
||||
+ }
|
||||
+ pub fn record_packet(&mut self, bytes: usize) {
|
||||
+ self.packets_since_update += 1;
|
||||
+ let _ = bytes;
|
||||
+ }
|
||||
+ pub fn update(&mut self) -> u32 {
|
||||
+ let new_state = if self.packets_since_update < 8 { ItrState::LowLatency }
|
||||
+ else if self.packets_since_update < 64 { ItrState::Moderate }
|
||||
+ else { ItrState::Bulk };
|
||||
+ if new_state != self.state {
|
||||
+ self.state = new_state;
|
||||
+ self.current_itr = match self.state {
|
||||
+ ItrState::LowLatency => ITR_LOW_LATENCY,
|
||||
+ ItrState::Moderate => ITR_DEFAULT,
|
||||
+ ItrState::Bulk => ITR_BULK,
|
||||
+ };
|
||||
+ }
|
||||
+ self.packets_since_update = 0;
|
||||
+ self.current_itr
|
||||
+ }
|
||||
+ pub fn current_itr(&self) -> u32 { self.current_itr }
|
||||
+}
|
||||
+
|
||||
+const E1000_ITR: u32 = 0x00C4;
|
||||
+
|
||||
+pub fn set_itr(device: &Intel8254x, itr_value: u32) {
|
||||
+ unsafe { device.write_reg(E1000_ITR, itr_value); }
|
||||
+}
|
||||
+
|
||||
+pub fn configure_default_itr(device: &Intel8254x) {
|
||||
+ set_itr(device, ITR_DEFAULT);
|
||||
+}
|
||||
+
|
||||
+pub fn configure_checksum_offload(device: &Intel8254x) {
|
||||
+ let rctl = unsafe { device.read_reg(0x0100) };
|
||||
+ unsafe { device.write_reg(0x0100, rctl | (1 << 4)) };
|
||||
+}
|
||||
+
|
||||
+pub fn enable_tso(device: &Intel8254x) {
|
||||
+ let tctl = unsafe { device.read_reg(0x0400) };
|
||||
+ unsafe { device.write_reg(0x0400, tctl | (1 << 11)) };
|
||||
+}
|
||||
diff --git a/drivers/net/rtl8168d/src/phy.rs b/drivers/net/rtl8168d/src/phy.rs
|
||||
new file mode 100644
|
||||
index 00000000..4f9def80
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/rtl8168d/src/phy.rs
|
||||
@@ -0,0 +1,42 @@
|
||||
+#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
+pub enum ChipVersion { Rtl8168b, Rtl8168c, Rtl8168cp, Rtl8168d, Rtl8168dp, Rtl8168e, Rtl8168evl, Rtl8168f, Rtl8168g, Rtl8168h, Rtl8168ep, Unknown }
|
||||
+
|
||||
+pub fn identify_chip(rev: u8, mac0: u32, _m1: u32, _m2: u32, _m3: u32, _m4: u32) -> ChipVersion {
|
||||
+ match ((mac0 >> 20) & 0x7, rev) {
|
||||
+ (0, _) => ChipVersion::Rtl8168b, (1, 0x00..=0x01) => ChipVersion::Rtl8168c, (1, 0x02) => ChipVersion::Rtl8168cp,
|
||||
+ (2, _) => ChipVersion::Rtl8168d, (3, r) if r <= 0x02 => ChipVersion::Rtl8168e, (3, _) => ChipVersion::Rtl8168evl,
|
||||
+ (4, _) => ChipVersion::Rtl8168f, (5, _) => ChipVersion::Rtl8168g, (6, _) => ChipVersion::Rtl8168h,
|
||||
+ (7, _) => ChipVersion::Rtl8168ep, _ => ChipVersion::Unknown,
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+pub mod phy_regs {
|
||||
+ pub const BMCR: u32 = 0x00; pub const BMSR: u32 = 0x01; pub const PHYID1: u32 = 0x02; pub const PHYID2: u32 = 0x03;
|
||||
+ pub const ANAR: u32 = 0x04; pub const ANLPAR: u32 = 0x05;
|
||||
+ pub const BMCR_RESET: u16 = 1 << 15; pub const BMCR_LOOPBACK: u16 = 1 << 14;
|
||||
+ pub const BMCR_SPEED_1000: u16 = 1 << 6; pub const BMCR_AUTONEG_ENABLE: u16 = 1 << 12;
|
||||
+ pub const BMCR_AUTONEG_RESTART: u16 = 1 << 9; pub const BMCR_DUPLEX: u16 = 1 << 8;
|
||||
+ pub const BMSR_AUTONEG_COMPLETE: u16 = 1 << 5; pub const BMSR_LINK_STATUS: u16 = 1 << 2;
|
||||
+}
|
||||
+
|
||||
+pub fn phy_link_up(read: &dyn Fn(u32) -> u16) -> bool { read(phy_regs::BMSR) & phy_regs::BMSR_LINK_STATUS != 0 }
|
||||
+
|
||||
+pub fn phy_reset(write: &dyn Fn(u32, u16), read: &dyn Fn(u32) -> u16) -> bool {
|
||||
+ write(phy_regs::BMCR, phy_regs::BMCR_RESET);
|
||||
+ for _ in 0..500 { if read(phy_regs::BMCR) & phy_regs::BMCR_RESET == 0 { return true; } }
|
||||
+ false
|
||||
+}
|
||||
+
|
||||
+pub fn phy_init_for_chip(chip: ChipVersion, write: &dyn Fn(u32, u16), _read: &dyn Fn(u32) -> u16) {
|
||||
+ match chip {
|
||||
+ ChipVersion::Rtl8168g | ChipVersion::Rtl8168h | ChipVersion::Rtl8168ep => {
|
||||
+ write(phy_regs::BMCR, phy_regs::BMCR_AUTONEG_ENABLE | phy_regs::BMCR_AUTONEG_RESTART | phy_regs::BMCR_SPEED_1000 | phy_regs::BMCR_DUPLEX);
|
||||
+ }
|
||||
+ _ => {
|
||||
+ write(phy_regs::BMCR, phy_regs::BMCR_AUTONEG_ENABLE | phy_regs::BMCR_AUTONEG_RESTART);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+pub fn set_jumbo_mtu(_write_phy: &dyn Fn(u32, u16), _mtu: u16) {
|
||||
+}
|
||||
diff --git a/drivers/storage/ahcid/src/ahci/ncq.rs b/drivers/storage/ahcid/src/ahci/ncq.rs
|
||||
new file mode 100644
|
||||
index 00000000..e08818f0
|
||||
--- /dev/null
|
||||
+++ b/drivers/storage/ahcid/src/ahci/ncq.rs
|
||||
@@ -0,0 +1,72 @@
|
||||
+use core::sync::atomic::{AtomicU32, Ordering};
|
||||
+
|
||||
+pub const NCQ_MAX_DEPTH: usize = 32;
|
||||
+
|
||||
+pub struct NcqState {
|
||||
+ pub sactive: AtomicU32,
|
||||
+ pub pending: AtomicU32,
|
||||
+}
|
||||
+
|
||||
+impl NcqState {
|
||||
+ pub const fn new() -> Self {
|
||||
+ Self { sactive: AtomicU32::new(0), pending: AtomicU32::new(0) }
|
||||
+ }
|
||||
+ pub fn allocate_tag(&self) -> Option<u32> {
|
||||
+ let active = self.pending.load(Ordering::Acquire);
|
||||
+ let free = !active;
|
||||
+ if free == 0 { return None; }
|
||||
+ let tag = free.trailing_zeros();
|
||||
+ let mask = 1u32 << tag;
|
||||
+ self.pending.fetch_or(mask, Ordering::AcqRel);
|
||||
+ self.sactive.fetch_or(mask, Ordering::AcqRel);
|
||||
+ Some(tag)
|
||||
+ }
|
||||
+ pub fn complete_tag(&self, tag: u32) {
|
||||
+ let mask = 1u32 << tag;
|
||||
+ self.sactive.fetch_and(!mask, Ordering::AcqRel);
|
||||
+ self.pending.fetch_and(!mask, Ordering::AcqRel);
|
||||
+ }
|
||||
+ pub fn has_pending(&self) -> bool { self.pending.load(Ordering::Acquire) != 0 }
|
||||
+}
|
||||
+
|
||||
+pub fn build_ncq_read_fis(tag: u32, lba: u64, count: u16) -> [u32; 5] {
|
||||
+ let mut f = [0u32; 5];
|
||||
+ f[0] = 0x0000_8027;
|
||||
+ f[1] = 0x0060 | ((count as u32 & 0xFF) << 24);
|
||||
+ f[2] = (lba as u32 & 0xFF) | (((lba >> 8) as u32 & 0xFF) << 8);
|
||||
+ let mid = ((lba >> 16) as u32 & 0xFF) | ((tag & 0x1F) << 3);
|
||||
+ f[3] = mid | (((lba >> 24) as u32 & 0xFF) << 8) | (((lba >> 32) as u32 & 0xFF) << 16) | (((lba >> 40) as u32 & 0xFF) << 24);
|
||||
+ f[4] = (((count >> 8) as u32 & 0xFF) << 16) | (((count >> 8) as u32 & 0xFF) << 24);
|
||||
+ f
|
||||
+}
|
||||
+
|
||||
+pub fn build_ncq_write_fis(tag: u32, lba: u64, count: u16) -> [u32; 5] {
|
||||
+ let mut f = build_ncq_read_fis(tag, lba, count);
|
||||
+ f[1] = (f[1] & !0xFF00) | 0x6100;
|
||||
+ f
|
||||
+}
|
||||
+
|
||||
+pub fn process_ncq_completions(old_sa: u32, new_sa: u32, ncq: &NcqState, completed: &mut [u32; NCQ_MAX_DEPTH]) -> usize {
|
||||
+ let mask = old_sa & !new_sa;
|
||||
+ if mask == 0 { return 0; }
|
||||
+ let mut count = 0;
|
||||
+ let mut m = mask;
|
||||
+ while m != 0 { let t = m.trailing_zeros(); ncq.complete_tag(t); completed[count] = t; count += 1; m &= m - 1; }
|
||||
+ count
|
||||
+}
|
||||
+
|
||||
+pub fn drive_supports_ncq(id: &[u16; 256]) -> bool { id.get(76).map_or(false, |w| w & (1 << 8) != 0) }
|
||||
+pub fn ncq_queue_depth(id: &[u16; 256]) -> u32 {
|
||||
+ id.get(75).map_or(1, |w| { let d = (w & 0x1F) as u32; if d > 0 { (d + 1).min(NCQ_MAX_DEPTH as u32) } else { 1 } })
|
||||
+}
|
||||
+
|
||||
+pub fn enable_ncq(hba_mem: &crate::ahci::hba::HbaMem, port_idx: usize) {
|
||||
+ let port = &hba_mem.ports[port_idx];
|
||||
+ let cmd = port.cmd.read();
|
||||
+ port.cmd.write(cmd | 1 << 1);
|
||||
+}
|
||||
+
|
||||
+pub fn issue_ncq_command(port: &crate::ahci::hba::HbaPort, tag: u32) {
|
||||
+ let ci = port.ci.read();
|
||||
+ port.ci.write(ci | (1u32 << tag));
|
||||
+}
|
||||
@@ -0,0 +1,34 @@
|
||||
--- a/src/scheme/debug.rs 2026-04-28 07:21:41.000000000 +0100
|
||||
+++ b/src/scheme/debug.rs 2026-05-04 08:10:23.688174541 +0100
|
||||
@@ -22,9 +22,10 @@
|
||||
|
||||
static HANDLES: RwLock<L1, HandleMap<Handle>> = RwLock::new(HandleMap::new());
|
||||
|
||||
-/// Add to the input queue
|
||||
+/// Add to the input queue, translating CR to NL (ICRNL) for serial console compatibility.
|
||||
pub fn debug_input(data: u8, token: &mut CleanLockToken) {
|
||||
- INPUT.send(data, token);
|
||||
+ let translated = if data == b'\r' { b'\n' } else { data };
|
||||
+ INPUT.send(translated, token);
|
||||
}
|
||||
|
||||
// Notify readers of input updates
|
||||
@@ -106,12 +107,16 @@
|
||||
fn fevent(
|
||||
&self,
|
||||
id: usize,
|
||||
- _flags: EventFlags,
|
||||
+ flags: EventFlags,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<EventFlags> {
|
||||
let _handle = *HANDLES.read(token.token()).get(id)?;
|
||||
|
||||
- Ok(EventFlags::empty())
|
||||
+ let mut ready = EventFlags::empty();
|
||||
+ if flags.contains(EventFlags::EVENT_READ) {
|
||||
+ ready |= EventFlags::EVENT_READ;
|
||||
+ }
|
||||
+ Ok(ready)
|
||||
}
|
||||
|
||||
fn fsync(&self, id: usize, token: &mut CleanLockToken) -> Result<()> {
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
--- a/redox-rt/src/arch/x86_64.rs 2026-04-28 07:19:14.000000000 +0100
|
||||
+++ b/redox-rt/src/arch/x86_64.rs 2026-05-04 08:13:45.179788927 +0100
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// Setup a stack starting from the very end of the address space, and then growing downwards.
|
||||
pub const STACK_TOP: usize = 1 << 47;
|
||||
-pub const STACK_SIZE: usize = 1024 * 1024;
|
||||
+pub const STACK_SIZE: usize = 8 * 1024 * 1024;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[repr(C)]
|
||||
@@ -0,0 +1,349 @@
|
||||
diff --git a/src/header/sys_resource/mod.rs b/src/header/sys_resource/mod.rs
|
||||
index 9166007a..c645e8eb 100644
|
||||
--- a/src/header/sys_resource/mod.rs
|
||||
+++ b/src/header/sys_resource/mod.rs
|
||||
@@ -92,7 +92,10 @@ pub unsafe extern "C" fn setpriority(which: c_int, who: id_t, nice: c_int) -> c_
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrlimit.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn getrlimit(resource: c_int, rlp: *mut rlimit) -> c_int {
|
||||
- let rlp = unsafe { Out::nonnull(rlp) };
|
||||
+ let Some(rlp) = (unsafe { Out::nullable(rlp) }) else {
|
||||
+ crate::platform::ERRNO.set(crate::header::errno::EFAULT);
|
||||
+ return -1;
|
||||
+ };
|
||||
|
||||
Sys::getrlimit(resource, rlp)
|
||||
.map(|()| 0)
|
||||
@@ -110,7 +113,12 @@ pub unsafe extern "C" fn setrlimit(resource: c_int, rlp: *const rlimit) -> c_int
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrusage.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
|
||||
- Sys::getrusage(who, unsafe { Out::nonnull(r_usage) })
|
||||
+ let Some(r_usage) = (unsafe { Out::nullable(r_usage) }) else {
|
||||
+ crate::platform::ERRNO.set(crate::header::errno::EFAULT);
|
||||
+ return -1;
|
||||
+ };
|
||||
+
|
||||
+ Sys::getrusage(who, r_usage)
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
diff --git a/src/header/unistd/mod.rs b/src/header/unistd/mod.rs
|
||||
index fdd1ff0d..9e3a20e9 100644
|
||||
--- a/src/header/unistd/mod.rs
|
||||
+++ b/src/header/unistd/mod.rs
|
||||
@@ -521,7 +521,7 @@ pub extern "C" fn getdtablesize() -> c_int {
|
||||
};
|
||||
if r == 0 {
|
||||
let cur = unsafe { lim.assume_init() }.rlim_cur;
|
||||
- match cur {
|
||||
+ return match cur {
|
||||
c if c < i32::MAX as u64 => c as i32,
|
||||
_ => i32::MAX,
|
||||
};
|
||||
diff --git a/src/header/unistd/sysconf/linux.rs b/src/header/unistd/sysconf/linux.rs
|
||||
index 2ec17eaf..8ec01d2d 100644
|
||||
--- a/src/header/unistd/sysconf/linux.rs
|
||||
+++ b/src/header/unistd/sysconf/linux.rs
|
||||
@@ -167,11 +167,33 @@ pub(super) fn sysconf_impl(name: c_int) -> c_long {
|
||||
// Values from musl which we can assume is correct.
|
||||
match name {
|
||||
_SC_CLK_TCK => 100,
|
||||
- // TODO: getrlimit
|
||||
- _SC_CHILD_MAX => -1,
|
||||
+ _SC_CHILD_MAX => {
|
||||
+ let mut lim = core::mem::MaybeUninit::<crate::header::sys_resource::rlimit>::uninit();
|
||||
+ let r = unsafe {
|
||||
+ crate::header::sys_resource::getrlimit(
|
||||
+ crate::header::sys_resource::RLIMIT_NPROC as c_int,
|
||||
+ lim.as_mut_ptr().cast::<crate::header::sys_resource::rlimit>(),
|
||||
+ )
|
||||
+ };
|
||||
+ if r == 0 {
|
||||
+ let cur = unsafe { lim.assume_init() }.rlim_cur;
|
||||
+ if cur == crate::header::sys_resource::RLIM_INFINITY { -1 } else if cur > c_long::MAX as u64 { c_long::MAX } else { cur as c_long }
|
||||
+ } else { -1 }
|
||||
+ }
|
||||
_SC_NGROUPS_MAX => NGROUPS_MAX as c_long,
|
||||
- // TODO: getrlimit
|
||||
- _SC_OPEN_MAX => -1,
|
||||
+ _SC_OPEN_MAX => {
|
||||
+ let mut lim = core::mem::MaybeUninit::<crate::header::sys_resource::rlimit>::uninit();
|
||||
+ let r = unsafe {
|
||||
+ crate::header::sys_resource::getrlimit(
|
||||
+ crate::header::sys_resource::RLIMIT_NOFILE as c_int,
|
||||
+ lim.as_mut_ptr().cast::<crate::header::sys_resource::rlimit>(),
|
||||
+ )
|
||||
+ };
|
||||
+ if r == 0 {
|
||||
+ let cur = unsafe { lim.assume_init() }.rlim_cur;
|
||||
+ if cur == crate::header::sys_resource::RLIM_INFINITY { -1 } else if cur > c_long::MAX as u64 { c_long::MAX } else { cur as c_long }
|
||||
+ } else { -1 }
|
||||
+ }
|
||||
_SC_STREAM_MAX => -1,
|
||||
// TODO: limits.h
|
||||
_SC_TZNAME_MAX => -1,
|
||||
diff --git a/src/header/unistd/sysconf/redox.rs b/src/header/unistd/sysconf/redox.rs
|
||||
index 97ee81aa..3d7f96dc 100644
|
||||
--- a/src/header/unistd/sysconf/redox.rs
|
||||
+++ b/src/header/unistd/sysconf/redox.rs
|
||||
@@ -5,7 +5,7 @@ use alloc::string::String;
|
||||
use crate::{
|
||||
error::Errno,
|
||||
fs::File,
|
||||
- header::{errno, fcntl, limits, sys_statvfs},
|
||||
+ header::{errno, fcntl, limits, sys_resource, sys_statvfs},
|
||||
io::Read,
|
||||
out::Out,
|
||||
platform::{
|
||||
@@ -65,14 +65,31 @@ pub const _SC_SIGQUEUE_MAX: c_int = 190;
|
||||
pub const _SC_REALTIME_SIGNALS: c_int = 191;
|
||||
// } POSIX.1
|
||||
|
||||
+fn resource_limit_sysconf(resource: c_int) -> c_long {
|
||||
+ let mut lim = core::mem::MaybeUninit::<sys_resource::rlimit>::uninit();
|
||||
+ let r = unsafe { sys_resource::getrlimit(resource, lim.as_mut_ptr()) };
|
||||
+ if r != 0 {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ let cur = unsafe { lim.assume_init() }.rlim_cur;
|
||||
+ if cur == sys_resource::RLIM_INFINITY {
|
||||
+ -1
|
||||
+ } else if cur > c_long::MAX as u64 {
|
||||
+ c_long::MAX
|
||||
+ } else {
|
||||
+ cur as c_long
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
pub(super) fn sysconf_impl(name: c_int) -> c_long {
|
||||
//TODO: Real values
|
||||
match name {
|
||||
_SC_ARG_MAX => 4096,
|
||||
- _SC_CHILD_MAX => 65536,
|
||||
+ _SC_CHILD_MAX => resource_limit_sysconf(sys_resource::RLIMIT_NPROC as c_int),
|
||||
_SC_CLK_TCK => 100,
|
||||
_SC_NGROUPS_MAX => limits::NGROUPS_MAX as c_long,
|
||||
- _SC_OPEN_MAX => 1024,
|
||||
+ _SC_OPEN_MAX => resource_limit_sysconf(sys_resource::RLIMIT_NOFILE as c_int),
|
||||
_SC_STREAM_MAX => 16,
|
||||
_SC_TZNAME_MAX => -1,
|
||||
_SC_VERSION => 200809,
|
||||
diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs
|
||||
index 8b5560e7..e6dcac55 100644
|
||||
--- a/src/platform/redox/mod.rs
|
||||
+++ b/src/platform/redox/mod.rs
|
||||
@@ -43,7 +43,7 @@ use crate::{
|
||||
sys_file,
|
||||
sys_mman::{MAP_ANONYMOUS, PROT_READ, PROT_WRITE},
|
||||
sys_random,
|
||||
- sys_resource::{RLIM_INFINITY, rlimit, rusage},
|
||||
+ sys_resource::{RLIM_INFINITY, RLIMIT_NLIMITS, rlimit, rusage},
|
||||
sys_select::timeval,
|
||||
sys_stat::{S_ISVTX, stat},
|
||||
sys_statvfs::statvfs,
|
||||
@@ -103,6 +103,32 @@ macro_rules! path_from_c_str {
|
||||
|
||||
static CLONE_LOCK: RwLock<()> = RwLock::new(());
|
||||
|
||||
+/// Per-process resource limits. Initialized with Linux-compatible defaults.
|
||||
+/// Inherited automatically across fork() (kernel copies address space).
|
||||
+const RLIMIT_DEFAULTS: [rlimit; RLIMIT_NLIMITS as usize] = [
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_CPU
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_FSIZE
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_DATA
|
||||
+ rlimit { rlim_cur: 8 * 1024 * 1024, rlim_max: RLIM_INFINITY }, // RLIMIT_STACK (8 MB soft)
|
||||
+ rlimit { rlim_cur: 0, rlim_max: RLIM_INFINITY }, // RLIMIT_CORE
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_RSS
|
||||
+ rlimit { rlim_cur: 4096, rlim_max: RLIM_INFINITY }, // RLIMIT_NPROC
|
||||
+ rlimit { rlim_cur: 1024, rlim_max: 1024 * 64 }, // RLIMIT_NOFILE
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_MEMLOCK
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_AS
|
||||
+ rlimit { rlim_cur: RLIM_INFINITY, rlim_max: RLIM_INFINITY }, // RLIMIT_LOCKS
|
||||
+ rlimit { rlim_cur: 4096, rlim_max: RLIM_INFINITY }, // RLIMIT_SIGPENDING
|
||||
+ rlimit { rlim_cur: 819200, rlim_max: RLIM_INFINITY }, // RLIMIT_MSGQUEUE
|
||||
+ rlimit { rlim_cur: 0, rlim_max: 0 }, // RLIMIT_NICE
|
||||
+ rlimit { rlim_cur: 0, rlim_max: 0 }, // RLIMIT_RTPRIO
|
||||
+];
|
||||
+
|
||||
+/// Runtime resource limits, mutable via setrlimit().
|
||||
+/// Inherited across fork() (kernel copies address space).
|
||||
+static RLIMIT_TABLE: RwLock<[rlimit; RLIMIT_NLIMITS as usize]> = RwLock::new(
|
||||
+ RLIMIT_DEFAULTS
|
||||
+);
|
||||
+
|
||||
/// Redox syscall implementation of [`Pal`].
|
||||
pub struct Sys;
|
||||
|
||||
@@ -729,21 +755,77 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn getrlimit(resource: c_int, mut rlim: Out<rlimit>) -> Result<()> {
|
||||
- todo_skip!(0, "getrlimit({}, {:p}): not implemented", resource, rlim);
|
||||
+ if resource < 0 || resource >= RLIMIT_NLIMITS as c_int {
|
||||
+ return Err(Errno(EINVAL));
|
||||
+ }
|
||||
+ let table = RLIMIT_TABLE.read();
|
||||
+ let current = &table[resource as usize];
|
||||
rlim.write(rlimit {
|
||||
- rlim_cur: RLIM_INFINITY,
|
||||
- rlim_max: RLIM_INFINITY,
|
||||
+ rlim_cur: current.rlim_cur,
|
||||
+ rlim_max: current.rlim_max,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn setrlimit(resource: c_int, rlim: *const rlimit) -> Result<()> {
|
||||
- todo_skip!(0, "setrlimit({}, {:p}): not implemented", resource, rlim);
|
||||
- Err(Errno(EPERM))
|
||||
+ if resource < 0 || resource >= RLIMIT_NLIMITS as c_int {
|
||||
+ return Err(Errno(EINVAL));
|
||||
+ }
|
||||
+ if rlim.is_null() {
|
||||
+ return Err(Errno(EFAULT));
|
||||
+ }
|
||||
+ let new = unsafe { &*rlim };
|
||||
+ if new.rlim_cur > new.rlim_max {
|
||||
+ return Err(Errno(EINVAL));
|
||||
+ }
|
||||
+ let mut table = RLIMIT_TABLE.write();
|
||||
+ let old = &table[resource as usize];
|
||||
+ if new.rlim_max > old.rlim_max {
|
||||
+ return Err(Errno(EPERM));
|
||||
+ }
|
||||
+ table[resource as usize] = rlimit {
|
||||
+ rlim_cur: new.rlim_cur,
|
||||
+ rlim_max: new.rlim_max,
|
||||
+ };
|
||||
+ Ok(())
|
||||
}
|
||||
|
||||
- fn getrusage(who: c_int, r_usage: Out<rusage>) -> Result<()> {
|
||||
- todo_skip!(0, "getrusage({}, {:p}): not implemented", who, r_usage);
|
||||
+ fn getrusage(who: c_int, mut r_usage: Out<rusage>) -> Result<()> {
|
||||
+ let clock_id = match who {
|
||||
+ 0 /* RUSAGE_SELF */ => 2 /* CLOCK_PROCESS_CPUTIME_ID */,
|
||||
+ 1 /* RUSAGE_THREAD */ => 3 /* CLOCK_THREAD_CPUTIME_ID */,
|
||||
+ -1 /* RUSAGE_CHILDREN */ => {
|
||||
+ r_usage.write(rusage {
|
||||
+ ru_utime: timeval { tv_sec: 0, tv_usec: 0 },
|
||||
+ ru_stime: timeval { tv_sec: 0, tv_usec: 0 },
|
||||
+ ru_maxrss: 0, ru_ixrss: 0, ru_idrss: 0, ru_isrss: 0,
|
||||
+ ru_minflt: 0, ru_majflt: 0, ru_nswap: 0,
|
||||
+ ru_inblock: 0, ru_oublock: 0, ru_msgsnd: 0, ru_msgrcv: 0,
|
||||
+ ru_nsignals: 0, ru_nvcsw: 0, ru_nivcsw: 0,
|
||||
+ });
|
||||
+ return Ok(());
|
||||
+ }
|
||||
+ _ => return Err(Errno(EINVAL)),
|
||||
+ };
|
||||
+
|
||||
+ let mut redox_tp = syscall::TimeSpec::default();
|
||||
+ let clock_result = syscall::clock_gettime(clock_id, &mut redox_tp);
|
||||
+
|
||||
+ let (tv_sec, tv_usec) = if clock_result.is_ok() {
|
||||
+ let ts: timespec = (&redox_tp).into();
|
||||
+ (ts.tv_sec, (ts.tv_nsec / 1000) as _)
|
||||
+ } else {
|
||||
+ (0, 0)
|
||||
+ };
|
||||
+
|
||||
+ r_usage.write(rusage {
|
||||
+ ru_utime: timeval { tv_sec, tv_usec },
|
||||
+ ru_stime: timeval { tv_sec: 0, tv_usec: 0 },
|
||||
+ ru_maxrss: 0, ru_ixrss: 0, ru_idrss: 0, ru_isrss: 0,
|
||||
+ ru_minflt: 0, ru_majflt: 0, ru_nswap: 0,
|
||||
+ ru_inblock: 0, ru_oublock: 0, ru_msgsnd: 0, ru_msgrcv: 0,
|
||||
+ ru_nsignals: 0, ru_nvcsw: 0, ru_nivcsw: 0,
|
||||
+ });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
diff --git a/tests/sys_resource/rlimit_roundtrip.c b/tests/sys_resource/rlimit_roundtrip.c
|
||||
new file mode 100644
|
||||
index 00000000..c90a6b79
|
||||
--- /dev/null
|
||||
+++ b/tests/sys_resource/rlimit_roundtrip.c
|
||||
@@ -0,0 +1,80 @@
|
||||
+#include <assert.h>
|
||||
+#include <errno.h>
|
||||
+#include <limits.h>
|
||||
+#include <stdio.h>
|
||||
+#include <sys/resource.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+int main(void) {
|
||||
+ struct rlimit original;
|
||||
+ struct rlimit current;
|
||||
+ struct rlimit invalid;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(getrlimit(RLIMIT_NOFILE, &original) == 0);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(getrlimit(RLIMIT_NLIMITS, ¤t) == -1);
|
||||
+ assert(errno == EINVAL);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(getrlimit(RLIMIT_NOFILE, NULL) == -1);
|
||||
+ assert(errno == EFAULT);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(getrusage(RUSAGE_SELF, NULL) == -1);
|
||||
+ assert(errno == EFAULT);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(setrlimit(RLIMIT_NOFILE, NULL) == -1);
|
||||
+ assert(errno == EFAULT);
|
||||
+
|
||||
+ invalid.rlim_cur = original.rlim_max;
|
||||
+ invalid.rlim_max = original.rlim_cur;
|
||||
+ errno = 0;
|
||||
+ assert(setrlimit(RLIMIT_NOFILE, &invalid) == -1);
|
||||
+ assert(errno == EINVAL);
|
||||
+
|
||||
+ if (original.rlim_max != RLIM_INFINITY) {
|
||||
+ invalid.rlim_cur = original.rlim_max + 1;
|
||||
+ invalid.rlim_max = original.rlim_max + 1;
|
||||
+ errno = 0;
|
||||
+ assert(setrlimit(RLIMIT_NOFILE, &invalid) == -1);
|
||||
+ assert(errno == EPERM);
|
||||
+ }
|
||||
+
|
||||
+ current.rlim_cur = original.rlim_cur > 16 ? original.rlim_cur - 16 : original.rlim_cur;
|
||||
+ current.rlim_max = original.rlim_max;
|
||||
+ errno = 0;
|
||||
+ assert(setrlimit(RLIMIT_NOFILE, ¤t) == 0);
|
||||
+
|
||||
+ struct rlimit roundtrip;
|
||||
+ errno = 0;
|
||||
+ assert(getrlimit(RLIMIT_NOFILE, &roundtrip) == 0);
|
||||
+ assert(roundtrip.rlim_cur == current.rlim_cur);
|
||||
+ assert(roundtrip.rlim_max == current.rlim_max);
|
||||
+
|
||||
+ long open_max = sysconf(_SC_OPEN_MAX);
|
||||
+ if (current.rlim_cur == RLIM_INFINITY) {
|
||||
+ assert(open_max == -1);
|
||||
+ } else if (current.rlim_cur > LONG_MAX) {
|
||||
+ assert(open_max == LONG_MAX);
|
||||
+ } else {
|
||||
+ assert(open_max == (long)current.rlim_cur);
|
||||
+ }
|
||||
+
|
||||
+ if (current.rlim_cur > INT_MAX) {
|
||||
+ assert(getdtablesize() == INT_MAX);
|
||||
+ } else {
|
||||
+ assert(getdtablesize() == (int)current.rlim_cur);
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ assert(setrlimit(RLIMIT_NOFILE, &original) == 0);
|
||||
+ assert(getrlimit(RLIMIT_NOFILE, &roundtrip) == 0);
|
||||
+ assert(roundtrip.rlim_cur == original.rlim_cur);
|
||||
+ assert(roundtrip.rlim_max == original.rlim_max);
|
||||
+
|
||||
+ puts("rlimit roundtrip ok");
|
||||
+ return 0;
|
||||
+}
|
||||
@@ -0,0 +1,67 @@
|
||||
diff --git a/res/issue b/res/issue
|
||||
index 6a963d8..092a432 100644
|
||||
--- a/res/issue
|
||||
+++ b/res/issue
|
||||
@@ -1,4 +1,4 @@
|
||||
-########## Redox OS ##########
|
||||
+########## RedBear OS ##########
|
||||
# Login with the following: #
|
||||
# `user` #
|
||||
# `root`:`password` #
|
||||
diff --git a/res/motd b/res/motd
|
||||
index 5cd097a..df2f802 100644
|
||||
--- a/res/motd
|
||||
+++ b/res/motd
|
||||
@@ -1,2 +1,2 @@
|
||||
-Welcome to Redox OS!
|
||||
+Welcome to RedBear OS!
|
||||
|
||||
diff --git a/src/bin/login.rs b/src/bin/login.rs
|
||||
index 08e178c..022fb47 100644
|
||||
--- a/src/bin/login.rs
|
||||
+++ b/src/bin/login.rs
|
||||
@@ -120,6 +120,7 @@ fn load_config_schemes(user: &User<redox_users::auth::Full>) -> Option<Vec<Strin
|
||||
pub fn main() {
|
||||
let mut stdout = io::stdout();
|
||||
let mut stderr = io::stderr();
|
||||
+ let mut consecutive_failures: u32 = 0;
|
||||
|
||||
let _args = clap_app!(login =>
|
||||
(author: "Jeremy Soller, Jose Narvaez")
|
||||
@@ -133,9 +134,13 @@ pub fn main() {
|
||||
}
|
||||
|
||||
loop {
|
||||
+ if consecutive_failures >= 3 {
|
||||
+ let delay_secs = std::cmp::min(consecutive_failures as u64, 30);
|
||||
+ std::thread::sleep(std::time::Duration::from_secs(delay_secs));
|
||||
+ }
|
||||
let user = liner::Context::new()
|
||||
.read_line(
|
||||
- liner::Prompt::from("\x1B[1mredox login:\x1B[0m "),
|
||||
+ liner::Prompt::from("\x1B[1mRedBear Login:\x1B[0m "),
|
||||
None,
|
||||
&mut liner::BasicCompleter::new(Vec::<String>::new()),
|
||||
)
|
||||
@@ -150,11 +155,13 @@ pub fn main() {
|
||||
None => {
|
||||
stdout.write(b"\nLogin incorrect\n").r#try(&mut stderr);
|
||||
stdout.write(b"\n").r#try(&mut stderr);
|
||||
+ consecutive_failures += 1;
|
||||
stdout.flush().r#try(&mut stderr);
|
||||
continue;
|
||||
}
|
||||
Some(user) => {
|
||||
if user.is_passwd_blank() {
|
||||
+ consecutive_failures = 0;
|
||||
if let Ok(mut motd) = File::open(MOTD_FILE) {
|
||||
io::copy(&mut motd, &mut stdout).r#try(&mut stderr);
|
||||
stdout.flush().r#try(&mut stderr);
|
||||
@@ -185,6 +192,7 @@ pub fn main() {
|
||||
stdout.flush().r#try(&mut stderr);
|
||||
|
||||
if user.verify_passwd(&password) {
|
||||
+ consecutive_failures = 0;
|
||||
if let Ok(mut motd) = File::open(MOTD_FILE) {
|
||||
io::copy(&mut motd, &mut stdout).r#try(&mut stderr);
|
||||
stdout.flush().r#try(&mut stderr);
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/base/P2-ihdad-graceful-init.patch
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/base/P6-driver-main-fixes.patch
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/base/P6-driver-new-modules.patch
|
||||
@@ -22,6 +22,7 @@ patches = [
|
||||
# P5-init-daemon-panic-hardening.patch
|
||||
# P5-init-supervisor-restart.patch
|
||||
"P2-i2c-gpio-ucsi-drivers.patch",
|
||||
"P2-ihdad-graceful-init.patch",
|
||||
"P9-fix-so-pecred.patch",
|
||||
"P3-inputd-keymap-bridge.patch",
|
||||
"P3-ps2d-led-feedback.patch",
|
||||
@@ -38,6 +39,9 @@ patches = [
|
||||
"P4-fbcond-scrollback.patch",
|
||||
"P4-thermal-daemon.patch",
|
||||
"P4-thermald-workspace.patch",
|
||||
"P6-driver-main-fixes.patch",
|
||||
"P6-driver-new-modules.patch",
|
||||
|
||||
]
|
||||
|
||||
[package]
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
# Consolidated patch: all Red Bear kernel changes (P0-P10) in a single file.
|
||||
# Individual patches preserved in local/patches/kernel/ for reference/rebase.
|
||||
# The consolidated patch was generated from applying: redox(no-op), P0-canary,
|
||||
# P1-memory-map-overflow, P4-supplementary-groups, P4-s3-suspend-resume,
|
||||
# P4-scheme-failure-modes, P5-sched-rt-policy, P5-scheme-sched-id,
|
||||
# P5-context-mod-sched, P6-percpu-runqueues, P6-futex-sharding,
|
||||
# P8-initial-placement, P9-proc-lock-ordering, P9-numa-topology,
|
||||
# P1-boot-path-diagnostics, P10-debug-scheme-serial-fix.
|
||||
# Patches that were cumulative supersets (P5-sched-policy-context, P5-proc-setschedpolicy,
|
||||
# P5-boot-path-hardening, P6-vruntime-*, P7-cache-affine-*, P7-proc-setname,
|
||||
# P7-proc-setpriority, P8-futex-requeue, P8-futex-pi, P8-futex-robust,
|
||||
# P8-percpu-wiring, P8-percpu-sched, P8-load-balance, P8-work-stealing,
|
||||
# P9-futex-pi-cas-fix) failed to apply at commit 866dfad0 due to
|
||||
# context conflicts and are deferred until rebase.
|
||||
[source]
|
||||
git = "https://gitlab.redox-os.org/redox-os/kernel.git"
|
||||
patches = ["redox.patch", "P0-canary.patch", "P1-memory-map-overflow.patch", "../../../local/patches/kernel/P4-supplementary-groups.patch", "../../../local/patches/kernel/P4-s3-suspend-resume.patch", "../../../local/patches/kernel/P4-scheme-failure-modes.patch", "../../../local/patches/kernel/P5-sched-policy-context.patch", "../../../local/patches/kernel/P5-sched-rt-policy.patch", "../../../local/patches/kernel/P5-proc-setschedpolicy.patch", "../../../local/patches/kernel/P5-scheme-sched-id.patch", "../../../local/patches/kernel/P5-context-mod-sched.patch", "../../../local/patches/kernel/P5-boot-path-hardening.patch", "../../../local/patches/kernel/P6-vruntime-context.patch", "../../../local/patches/kernel/P6-percpu-runqueues.patch", "../../../local/patches/kernel/P6-futex-sharding.patch", "../../../local/patches/kernel/P6-vruntime-switch.patch", "../../../local/patches/kernel/P7-cache-affine-context.patch", "../../../local/patches/kernel/P7-cache-affine-switch.patch", "../../../local/patches/kernel/P7-proc-setname.patch", "../../../local/patches/kernel/P7-proc-setpriority.patch", "../../../local/patches/kernel/P8-futex-requeue.patch", "../../../local/patches/kernel/P8-futex-pi.patch", "../../../local/patches/kernel/P8-futex-robust.patch", "../../../local/patches/kernel/P8-percpu-wiring.patch", "../../../local/patches/kernel/P8-percpu-sched.patch", "../../../local/patches/kernel/P9-proc-lock-ordering.patch", "../../../local/patches/kernel/P9-futex-pi-cas-fix.patch", "../../../local/patches/kernel/P1-boot-path-diagnostics.patch"]
|
||||
rev = "866dfad0"
|
||||
patches = ["../../../local/patches/kernel/redbear-consolidated.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/kernel/redbear-consolidated.patch
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/relibc/P10-stack-size-8mb.patch
|
||||
@@ -0,0 +1 @@
|
||||
../../../local/patches/relibc/P11-getrlimit-getrusage.patch
|
||||
@@ -1,6 +1,6 @@
|
||||
[source]
|
||||
git = "https://gitlab.redox-os.org/redox-os/relibc.git"
|
||||
patches = ["P5-named-semaphores.patch"]
|
||||
patches = ["P10-stack-size-8mb.patch", "P11-getrlimit-getrusage.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[source]
|
||||
git = "https://gitlab.redox-os.org/redox-os/userutils.git"
|
||||
patches = ["P4-login-rate-limit.patch"]
|
||||
patches = ["P5-redbear-branding.patch"]
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
|
||||
Reference in New Issue
Block a user