{"id":15565171,"url":"https://github.com/textshell/posixsignalmanager","last_synced_at":"2025-09-05T17:37:28.277Z","repository":{"id":200213407,"uuid":"490457354","full_name":"textshell/posixsignalmanager","owner":"textshell","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-15T20:37:29.000Z","size":270,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-15T21:57:20.105Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/textshell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-05-09T22:02:04.000Z","updated_at":"2025-06-15T20:37:33.000Z","dependencies_parsed_at":"2023-12-28T00:15:37.223Z","dependency_job_id":"8c5db158-090f-4cdd-b035-1f76839fae1d","html_url":"https://github.com/textshell/posixsignalmanager","commit_stats":null,"previous_names":["textshell/posixsignalmanager"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/textshell/posixsignalmanager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textshell%2Fposixsignalmanager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textshell%2Fposixsignalmanager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textshell%2Fposixsignalmanager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textshell%2Fposixsignalmanager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/textshell","download_url":"https://codeload.github.com/textshell/posixsignalmanager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/textshell%2Fposixsignalmanager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273791430,"owners_count":25168882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-05T02:00:09.113Z","response_time":402,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T16:51:27.876Z","updated_at":"2025-09-05T17:37:28.232Z","avatar_url":"https://github.com/textshell.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n    Posix Signal Manager\n\u003c/h1\u003e\n\nLibrary safe, synchronous and asynchronous handling of posix signals for Qt applications and libraries.\n\n## Why?\n\nThe interface of libc for posix signals is not library safe, as each signal can only have one handler.\nThis library offers an interface where multiple parts of an application can share access to signals.\n\nThe easiest way is to use `PosixSignalNotifier` to convert posix signals to a Qt signal. The Qt signal is delivered\nvia the Qt event loop and thus it is safe to use all the usual apis available to the application.\n\nIt is also possible to register handlers for crashes (SIGSEGV etc) or signal based termination (SIGINT, SIGTERM, etc)\nusing `PosixSignalManager::addSyncCrashHandler` and `PosixSignalManager::addSyncTerminationHandler` to add emergency\ncleanup. These handlers have to be\n[async signal safe](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03),\nwhich is a quite restrictive environment.\n\nIf waiting for a event loop iteration is not acceptable or the signal is of a type that can only be handled directly\nfrom a posix signal handler there is also the possiblity to use `PosixSignalManager::addSyncSignalHandler` to register\nhandlers that run directly in the async signal context. Again these handlers have to be \n[async signal safe](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03),\nwhich is a quite restrictive environment. Synchronous handlers can stop processing the signal or mark it to be reraised.\n\n## Alternatives\n\nOften using signals is not the best way to achieve robust code. If possible consider alternatives to signals.\n\n* process management: [pidfd(linux)](https://man7.org/linux/man-pages/man2/pidfd_open.2.html), [pdfork(freebsd)](https://www.freebsd.org/cgi/man.cgi?query=pdfork\u0026sektion=2)\n* timers: [QTimer](https://doc.qt.io/qt-5/qtimer.html) [timerfd](https://man7.org/linux/man-pages/man2/timerfd_create.2.html)\n* interprocess communication: [dbus](https://doc.qt.io/qt-5/qtdbus-index.html) see also [dbus @ freedesktop](https://www.freedesktop.org/wiki/Software/dbus/)\n\n## Building / Installing\n\n    $ meson setup -Dprefix=$HOME/opt/signalmanager/ _build\n    $ ninja -C _build\n    $ ninja -C _build install\n\n## Examples\n\n### Reload configuration on SIGHUP\n\nThis example handles SIGHUP using a Qt signal on a future event loop iteration.\n\n``` cpp\n    if (!PosixSignalManager::isCreated()) PosixSignalManager::create();\n    auto* notifier = new PosixSignalNotifier(SIGHUP, parent);\n    QObject::connect(notifier, \u0026PosixSignalNotifier::activated, parent, \u0026SomeClass::reloadConfig);\n```\n\n### Quit gracefully on SIGTERM\n\nThis example handles SIGTERM by terminating the event loop on a future event loop iteration.\n\n``` cpp\n    if (!PosixSignalManager::isCreated()) PosixSignalManager::create();\n    auto* notifier = new PosixSignalNotifier(SIGTERM, parent);\n    QObject::connect(notifier, \u0026PosixSignalNotifier::activated, QCoreApplication::instance(),\n                     [](auto signal, auto info) { QCoreApplication::instance()-\u003equit(); });\n```\n\nIf the program is prone to get stuck without servicing the event loop and a further SIGTERM should be usable to do\nan emergency stop it is possible to combine the Qt signal based clean shutdown with an emergency shutdown from the\nsignal handler\n\n``` cpp\n    if (!PosixSignalManager::isCreated()) PosixSignalManager::create();\n    auto* notifier = new PosixSignalNotifier(SIGTERM, parent);\n    QObject::connect(notifier, \u0026PosixSignalNotifier::activated, QCoreApplication::instance(),\n                     [](auto signal, auto info) { QCoreApplication::instance()-\u003equit(); });\n    auto* manager = PosixSignalManager::instance();\n    manager-\u003eaddSyncSignalHandler(SIGTERM, [](void *data, PosixSignalFlags \u0026flags, const siginfo_t *info, void *context) {\n        static std::atomic\u003cint\u003e count = 0;\n        if (count == 0) {\n            flags.clearReraise();\n        } else {\n            // emergency shutdown here\n            // maybe remove a pid file or some other externally visible cleanup\n            \n            // request posix signal manager to terminate application as if no signal handler had been set\n            flags.reraise();\n            // or as alternative\n            // _exit(1);            \n        }\n        ++count;\n    }, nullptr);\n```\n\n\n## Documentation\n\nBefore most functionality of this library can be used, its main singleton must be created.\nApplications may only create this singleton once.\n\nIf a library wants to detect if PosixSignalManager is already in use it can detect this by calling\n`PosixSignalManager::isCreated()`. If usage of PosixSignalManager is optional the library can then either use\nPosixSignalManager or can fall back to using sigaction.\nOtherwise all users should ensure to call `PosixSignalManager::create()` if the singleton was not yet created and\nproceed with usage.\n\nThe instance of the singleton can be retrieved using `PosixSignalManager::instance`.\n\nAfter the singleton is created the main interfaces of PosixSignalManager are `PosixSignalNotifier` for message loop\nbased signal processing and `PosixSignalManager` for low level synchronous signal handling.\n\n### PosixSignalNotifier\n\n`PosixSignalNotifier` is the easiest way to handle the usual signals used for communication.\nJust create an instance and pass the signal number to catch as the first constructor argument and connect your handler\nto the `activated` signal of the instance.\n\nThe `activated` signal passes the number of the caught signal as the first parameter and the full signal details as a\n`siginfo_t` structure in the second parameter.\n\nSignals handled with this class are processed in the event loop of the thread that called its constructor as soon as\nthat event loop reacts the newly available data in PosixSignalNotifier's internal pipe.\n\nIf the instance of PosixSignalNotifier is deleted the signal handling reverts back.\nAlthough the low level event handler is not removed, PosixSignalManager will emulate the signals default action when no\nPosixSignalNotifier instances or synchronous handlers remain.\n\nThis class is not suitable to handle crash signals such as \"Segmentation Fault\"(SIGSEGV), \"Bus Error\"(SIGBUS),\n\"Illegal Instruction\"(SIGILL), \"Floating Point Error\"(SIGFPE) and similar signals.\n\n### PosixSignalManager\n\nIf handling the signal via PosixSignalNotifier is not enough PosixSignalManager offers an interface to hook into the\nsignal's low level handler. All handler functions used with PosixSignalManager must be\n[async signal safe](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03)\n([linux](https://man7.org/linux/man-pages/man7/signal-safety.7.html)).\nThat means most functions and methods one would usually use are not permitted to be called in signal handling functions.\nThis includes all of Qt, most of the c++ standard library(always lookfree std::atomic should be ok) and even most of the\nstandard c library. Also calling (sig)longjump from synchronous handlers is not supported in this library.\n\nAll handlers are executed in the order of their registration.\n\nOne common use case is to register cleanup handlers using `PosixSignalManager::addSyncCrashHandler` and\n`PosixSignalManager::addSyncTerminationHandler` to do last moment cleanup before a process dies due to an otherwise\nunhandled signal.\nThe handlers registered using these methods always run after all other handlers and only if the signal is not marked as\nhandled or handled using `PosixSignalNotifier`.\n\nThe crash handlers are called on signals normally associated with process crashes or failed assertations (like SIGSEGV,\nSIGBUS, SIGABRT, etc). Crash handlers are also suitable to print or log crash information.\n\nThe termination handlers are called on signals that are fatal that are not crash signals.\n\nTermination handler can not stop or modify signal propagation(except calling abort, _exit or similar).\n\nFor synchronous handling of signals `PosixSignalManager::addSyncSignalHandler` can be used.\nThis method registers a handler for a specific signal.\nThe signal handler can influence the further processing of the signal by calling methods on the `PosixSignalFlags`\nobject passed as its second parameter.\nTo prevent the default action of the signal (which is often process termination) the handler should call\n`PosixSignalFlags::clearReraise` if it could handle the signal.\nMost handlers for communication signals should always call this method, on the other hand handlers that can only handle\na subset of possible signal causes (like SIGSEGV/SIGBUS handlers for specific data or code segments) should call\nclearReraise only if they could handle or fix the cause of the signal.\nThe existance of an instance of `PosixSignalNotifier` implicitly disables reraise of a signal.\nIn addition handlers can suppress calling of later registered handlers for the same signal by calling\n`PosixSignalFlags::stopChain`.\n\nAll handler registrations return an `int` registration id that can be used with `PosixSignalManager::removeHandler`\nto remove the handler when no longer needed.\nAlthough the low level event handler is not removed PosixSignalManager will emulate the signals default action when\nno PosixSignalNotifier instances or synchronous handlers remain.\n\nVariables used from the signal or termination handlers need to be threated with special care as these can be accessed\nfrom the handlers any time while they are manipulated. Even locally blocking the signal will not prevent this in\nmultithreaded processes. Thus it is safest to always use lock free algorithms that atomically replace old state with\nnew state. To help with freeing previously used memory after swaping to a new state, PosixSignalManager offers\n`PosixSignalManager::barrier` which guarantees that every handler that was running before the call started has\nterminated after the call returns.\n\n## Compatiblity and Porting\n\nThe main library needs little porting to not yet supported posix-like operating systems. The main concern is updating\nthe conditions for default fatal signals and possibly updating what method to use to reraise crash signals.\n\nThe tests cover many edge cases and are more work to port.\n\nThis library currently is known to work and pass its tests on:\nLinux (\u003e= 4.14, various distros, glibc and musl), FreeBSD, OpenBSD, NetBSD, Illumos and Apple.\n\n## License\n\nPosixSignalManager is licensed under the [Boost Software License 1.0](COPYING)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftextshell%2Fposixsignalmanager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftextshell%2Fposixsignalmanager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftextshell%2Fposixsignalmanager/lists"}