From a186857126d69b62be664abfdcfbabaccf02f126 Mon Sep 17 00:00:00 2001 From: stswangzhiping <59632378+stswangzhiping@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:53:21 +0800 Subject: [PATCH] fix(network): auto-cache LAN iface for carrier when CLAWD_ETH_IFACE unset First getWiredIfaceWithCarrier() result locks _lanMonitoredIface; subsequent hasLanCableCarrier only reads that sysfs carrier so unplug reliably turns LAN off. CLAWD_ETH_IFACE still overrides. Made-with: Cursor --- lib/network.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/network.js b/lib/network.js index f9f58f1..23af83c 100644 --- a/lib/network.js +++ b/lib/network.js @@ -62,9 +62,12 @@ function hasWiredCarrier() { return getWiredIfaceWithCarrier() !== null; } +/** LAN 灯:未配 CLAWD_ETH_IFACE 时,首次见 carrier 的有线口会缓存,之后只读该口(拔线即灭) */ +let _lanMonitoredIface = null; + /** - * LAN 面板灯专用:若设置 CLAWD_ETH_IFACE,只认该口 carrier(拔网线必灭); - * 未设置时退回 hasWiredCarrier()(可能受其它网口影响,建议在 box 上配置 end0 等)。 + * LAN 面板灯专用:优先 CLAWD_ETH_IFACE;否则自动锁定首次出现的 getWiredIfaceWithCarrier(), + * 之后仅看该口 carrier(避免「任意有线」与其它虚拟口混淆)。多口同时在线时仍以扫描序为准,可用手动 env 覆盖。 */ function hasLanCableCarrier() { const explicit = process.env.CLAWD_ETH_IFACE; @@ -75,7 +78,20 @@ function hasLanCableCarrier() { return false; } } - return hasWiredCarrier(); + + if (_lanMonitoredIface) { + try { + return fs.readFileSync(`/sys/class/net/${_lanMonitoredIface}/carrier`, 'utf8').trim() === '1'; + } catch (_) { + _lanMonitoredIface = null; + return false; + } + } + + const wired = getWiredIfaceWithCarrier(); + if (!wired) return false; + _lanMonitoredIface = wired; + return true; } function _tryPingInternet() {