{"record":{"id":"dd4f4d03db181177","repo":"bootandy/dust","slug":"error-setting-ctrl-c-handler","errorCode":null,"errorMessage":"Error setting Ctrl-C handler","messagePattern":"Error setting Ctrl-C handler","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":129,"sourceCode":"                process::exit(1)\n            })\n        })\n        .collect()\n}\n\nfn main() {\n    let options = Cli::parse();\n    let config = get_config(options.config.as_ref());\n\n    let errors = RuntimeErrors::default();\n    let error_listen_for_ctrlc = Arc::new(Mutex::new(errors));\n    let errors_for_rayon = error_listen_for_ctrlc.clone();\n\n    ctrlc::set_handler(move || {\n        println!(\"\\nAborting\");\n        process::exit(1);\n    })\n    .expect(\"Error setting Ctrl-C handler\");\n\n    let target_dirs = if let Some(path) = config.get_files0_from(&options) {\n        read_paths_from_source(&path, true)\n    } else if let Some(path) = config.get_files_from(&options) {\n        read_paths_from_source(&path, false)\n    } else {\n        match options.params {\n            Some(ref values) => values.clone(),\n            None => vec![\".\".to_owned()],\n        }\n    }\n    .into_iter()\n    .filter(|path| !path.is_empty())\n    .collect::<Vec<_>>();\n\n    let summarize_file_types = options.file_types;\n\n    let filter_regexs = get_regex_value(options.filter.as_ref());","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/bootandy/dust/blob/8a846f6689f2db6be6ef595239a21ec784d62b57/src/main.rs#L111-L147","documentation":"This panic comes from `.expect()` on the `Result` returned by `ctrlc::set_handler`, which registers a SIGINT (Ctrl-C) handler for the process. The ctrlc crate throws this error when it fails to install the OS-level signal handler — typically because the underlying OS API (signal/sigaction on Unix, SetConsoleCtrlHandler on Windows) failed, or because the internal wakeup pipe/socket could not be created.","triggerScenarios":"Calling `ctrlc::set_handler` when: (1) the OS refuses to install a signal handler (e.g. signal/sigaction returns an error), (2) the crate cannot create its internal self-pipe (pipe/socketpair failure, often fd exhaustion or a hardened seccomp/sandbox blocking pipe2), (3) running in an environment without a proper signal mechanism (some containers, CI sandboxes, or processes with a masked/disabled signal mask), or (4) set_handler is invoked in a context where registering handlers is not permitted.","commonSituations":"Running the binary inside a restricted container or sandbox (Docker with restricted syscall filters, gVisor, seccomp profiles) that blocks pipe2/signal syscalls; processes with exhausted file descriptors so the ctrlc self-pipe cannot be created; embedding the program as a PID-1 process or in environments where signal handlers cannot be registered; uncommon but possible resource exhaustion at startup.","solutions":["Check the environment the program runs in: remove seccomp/sandbox syscall restrictions blocking pipe2 or signal installation, and raise the file-descriptor limit (ulimit -n).","Call `ctrlc::set_handler` and handle the Err case gracefully instead of panicking, so the tool still runs (just without Ctrl-C handling): `if let Err(e) = ctrlc::set_handler(...) { eprintln!(\"warning: Ctrl-C handling unavailable: {e}\"); }`.","Ensure ctrlc runs only once per process and before threads that matter are spawned; a second set_handler call or a mis-sequenced init can fail.","Update the ctrlc crate to the latest version; older versions had platform-specific handler-installation bugs.","If the environment genuinely cannot support signal handlers (e.g. some embedded/WASI targets), drop the ctrlc dependency or gate it behind a feature flag / target check."],"exampleFix":"// before\nctrlc::set_handler(move || {\n    println!(\"\\nAborting\");\n    process::exit(1);\n})\n.expect(\"Error setting Ctrl-C handler\");\n// after\nif let Err(e) = ctrlc::set_handler(move || {\n    println!(\"\\nAborting\");\n    process::exit(1);\n}) {\n    eprintln!(\"warning: could not install Ctrl-C handler: {e}\");\n}","handlingStrategy":"fallback","validationCode":"// No portable pre-check exists; detect the environment that breaks ctrlc:\n// e.g. check fd availability before startup\nmatch std::fs::File::create(\"/dev/null\") {\n    Ok(_) => {},\n    Err(e) => eprintln!(\"fd exhaustion likely ({e}); signal handler may fail to install\"),\n}","typeGuard":"fn ctrlc_supported() -> bool {\n    #[cfg(any(target_os = \"linux\", target_os = \"macos\", target_os = \"windows\"))]\n    { true }\n    #[cfg(not(any(target_os = \"linux\", target_os = \"macos\", target_os = \"windows\")))]\n    { false }\n}","tryCatchPattern":"match ctrlc::set_handler(|| {\n    eprintln!(\"\\nAborting\");\n    std::process::exit(1);\n}) {\n    Ok(()) => {}\n    Err(e) => eprintln!(\"warning: Ctrl-C handling unavailable: {e}\"),\n}","preventionTips":["Never `.expect()`/`.unwrap()` on set_handler in a CLI tool — degrade to running without a handler instead of aborting startup.","Avoid running signal-handler setup inside restricted sandboxes/seccomp profiles; test container images with the same syscall filters as production.","Keep the ctrlc crate updated and register the handler once, early in main, before spawning worker threads.","Monitor file-descriptor usage; fd exhaustion breaks ctrlc's internal self-pipe."],"tags":["rust","ctrlc","signal-handling","panic"],"backgroundTag":"signal-handler-registration-failed","analyzedSha":"8a846f6689f2db6be6ef595239a21ec784d62b57","analyzedAt":"2026-09-08T04:03:42.095Z","contentChangedAt":"2026-09-08T04:03:42.095Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}