rust-lang/rust · error · io::Error

process groups are not supported on espidf

Error message

process groups are not supported on espidf

What it means

ChildExt::kill_process_group sends SIGKILL to a child's process group. On the espidf target (ESP-IDF / FreeRTOS) the OS has no process-group concept, so the method is compiled (#[cfg(target_os = "espidf")]) but unconditionally returns Err(io::ErrorKind::Unsupported) (process.rs:580-586).

Source

Thrown at library/std/src/os/unix/process.rs:582

#[unstable(feature = "unix_send_signal", issue = "141975")]
impl ChildExt for process::Child {
    fn send_signal(&self, signal: i32) -> io::Result<()> {
        self.handle.send_signal(signal)
    }

    fn send_process_group_signal(&self, signal: i32) -> io::Result<()> {
        self.handle.send_process_group_signal(signal)
    }

    #[cfg(not(target_os = "espidf"))]
    fn kill_process_group(&mut self) -> io::Result<()> {
        self.handle.send_process_group_signal(libc::SIGKILL)
    }

    #[cfg(target_os = "espidf")]
    fn kill_process_group(&mut self) -> io::Result<()> {
        Err(io::Error::new(
            io::ErrorKind::Unsupported,
            "process groups are not supported on espidf",
        ))
    }
}

#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawFd for process::Stdio {
    #[inline]
    unsafe fn from_raw_fd(fd: RawFd) -> process::Stdio {
        let fd = sys::fd::FileDesc::from_raw_fd(fd);
        let io = sys::process::Stdio::Fd(fd);
        process::Stdio::from_inner(io)
    }
}

#[stable(feature = "io_safety", since = "1.63.0")]
impl From<OwnedFd> for process::Stdio {

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Gate the call with #[cfg(not(target_os = "espidf"))] and fall back to child.kill() on espidf.
  2. At runtime, match on io::ErrorKind::Unsupported and degrade to child.kill().
  3. Avoid kill_process_group entirely on no-process-group platforms.

Example fix

// before
child.kill_process_group()?;
// after
#[cfg(not(target_os = "espidf"))]
child.kill_process_group()?;
#[cfg(target_os = "espidf")]
child.kill()?
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time gate: only call kill_process_group where it is supported.
#[cfg(not(target_os = "espidf"))]
fn kill_group(child: &mut std::process::Child) -> std::io::Result<()> {
    use std::os::unix::process::ChildExt;
    child.kill_process_group()
}
#[cfg(target_os = "espidf")]
fn kill_group(child: &mut std::process::Child) -> std::io::Result<()> {
    child.kill() // no process groups on espidf
}

Try / catch

match child.kill_process_group() {
    Ok(()) => {},
    Err(e) if e.kind() == std::io::ErrorKind::Unsupported => {
        let _ = child.kill();
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `child.kill_process_group()` in code compiled for `target_os = "espidf"` (e.g. ESP32 firmware).

Common situations: Cross-platform process-management code that calls kill_process_group unconditionally; targeting ESP32/ESP8266 boards.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/18cd38bb369447ec. Report an issue: GitHub.