Ctrl-C Manifesto

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • Appwrite - The Open Source Firebase alternative introduces iOS support
  • talent.io - Download talent.io’s Tech Salary Report
  • Scout APM - Less time debugging, more time building
  • SonarQube - Static code analysis for 29 languages.
  • bc

    An implementation of the POSIX bc calculator with GNU extensions and dc, moved away from GitHub. Finished, but well-maintained.

    Surprisingly, it is possible to do exactly what the author wants. I know because I've done it. However, it is as complicated as the author says it is.

    The project in question is my `bc` [1].

    Until version 3.0.0 [2], it used a "yield" architecture: every loop it could enter had a check for a signal. This got tedious, so I decided to make the jump to instant-ish reset.

    I was lucky in several ways. First, `bc` is a really good program to reset; you just stop it executing, wipe all data away, and ask for more input with a blank slate. Second, it is single-threaded.

    Nevertheless, it was still really difficult, especially to have no memory leaks.

    First, I had to learn how to use `sigsetjmp()` and `siglongjmp()`. Yep, that was how I was going to do this. Once I learned, I implemented a stack of `sigjmp_buf`'s. Then, when a signal happens, each individual `sigjmp_buf` is used. This allowed me to properly free memory on the way.

    In essence, if a function had allocated memory, then it would push a `sigjmp_buf` on the stack, and then when a `siglongjmp()` happened, execution would go to a label where that memory would be freed before continuing the jump series.

    Then I implemented signal locks. It is safe to `siglongjmp()` out of signal handler, as long as it didn't interrupt code that was non-async-signal-safe. So I used signal locks for that, and when "unlocking" the lock, it would check for a signal and jump. And if the signal handler sees a lock, it just sets a flag and returns.

    Then I had to go through my codebase and protect every bit of non-async-signal-safe code with locks. It was tedious, but the result is fantastic.

    Nowadays, I'm working on a threaded build system, and when it gets SIGINT, it sends a message to threads to stop as soon as their children are done. If it receives a second, it just exits.

    So yeah, every application is different, but it is possible.

    [1]: https://git.yzena.com/gavin/bc

    [2]: https://git.yzena.com/gavin/bc/src/branch/master/NEWS.md#3-0...

  • prompts

    ❯ Lightweight, beautiful and user-friendly interactive prompts

    Would love if prompts fixed this so it was easy to implement in my CLI app: https://github.com/terkelg/prompts/issues/252

  • Appwrite

    Appwrite - The Open Source Firebase alternative introduces iOS support . Appwrite is an open source backend server that helps you build native iOS applications much faster with realtime APIs for authentication, databases, files storage, cloud functions and much more!

  • SimplestLoadBalancer

    This is an implementation of a sessionless/stateless UDP load balancer that evenly distributes packets to back-end targets, and with low-latency target management (add and remove).

    Maybe I’m missing the point, but this (essentially random example) is multithreaded (asynchronous) and gracefully handles ctrl-c. Yes, it’s a high level language that makes it easy, I guess.


NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts