{"id":46344798,"url":"https://github.com/aremmell/libbal","last_synced_at":"2026-03-04T21:09:07.099Z","repository":{"id":10029716,"uuid":"12071912","full_name":"aremmell/libbal","owner":"aremmell","description":"Berkeley Abstraction Layer: a lightweight, portable C17/C++20 wrapper library for Berkeley sockets (with asynchronous I/O and IPv6 support)","archived":false,"fork":false,"pushed_at":"2025-12-21T13:07:54.000Z","size":412,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-23T03:21:19.921Z","etag":null,"topics":["abstraction-layer","async-io","asynchronous","berkeley-sockets","c17","cpp20","ipv6","portable-library"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aremmell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2013-08-13T03:03:03.000Z","updated_at":"2025-12-21T13:07:57.000Z","dependencies_parsed_at":"2024-01-07T11:27:19.464Z","dependency_job_id":"1863f99f-6a05-4384-9cd9-947fe60e89ee","html_url":"https://github.com/aremmell/libbal","commit_stats":null,"previous_names":["aremmell/libbal"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/aremmell/libbal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aremmell%2Flibbal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aremmell%2Flibbal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aremmell%2Flibbal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aremmell%2Flibbal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aremmell","download_url":"https://codeload.github.com/aremmell/libbal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aremmell%2Flibbal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30093072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T20:42:30.420Z","status":"ssl_error","status_checked_at":"2026-03-04T20:42:30.057Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["abstraction-layer","async-io","asynchronous","berkeley-sockets","c17","cpp20","ipv6","portable-library"],"created_at":"2026-03-04T21:09:06.468Z","updated_at":"2026-03-04T21:09:07.088Z","avatar_url":"https://github.com/aremmell.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libbal\n\n\u003c!-- SPDX-License-Identifier: MIT --\u003e\n\u003c!-- Copyright (c) 2004-2025 Ryan M. Lederman \u003clederman@gmail.com\u003e --\u003e\n\n[![License](https://img.shields.io/github/license/aremmell/libbal?color=%2340b900\u0026cacheSeconds=60)](https://github.com/aremmell/libbal/blob/master/LICENSE)\n[![REUSE status](https://api.reuse.software/badge/github.com/aremmell/libbal)](https://api.reuse.software/info/github.com/aremmell/libbal)\n[![Codacy Badge](https://app.codacy.com/project/badge/Grade/a7e6cfb38dc44542b34b9ce447fcc792)](https://app.codacy.com/gh/aremmell/libbal/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=aremmell_libbal\u0026metric=security_rating)](https://sonarcloud.io/summary/new_code?id=aremmell_libbal)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=aremmell_libbal\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=aremmell_libbal)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=aremmell_libbal\u0026metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=aremmell_libbal)\n\n`libbal`: a lightweight, portable C17/C++20 abstraction layer for Berkeley Sockets, complete with asynchronous I/O and *no third-party depdendencies*.\n\n## UPDATE December 2025\n\nI'll be getting to documentation in the new year. No, I'm not going to use Claude, hipster.\n\nI'm also considering branching off and converting everything to C23, since I've wanted to write `nullptr` in C for around 15 years. Yes, for that reason alone; wanna fight about it?\n\nAnd finally, it looks like I have the \"quirky\" folks who maintain CMake to thank for wasting my time resolving various warnings that emerged from the ether in a project whose source code hasn't changed\u0026mdash;only the version of CMake on my machine. It's called backwards compatibility, people. Knock it off already. Nobody's ever going to use `-Wno-dev` unironically.\n\n## UPDATE January 2025\n\nI have set up a simplistic GitHub CMake action that will test compilation on Windows/Ubuntu/macOS with Clang/gcc/cl. This revealed several problems related to compiler versioning and portability, which are now fixed. I have tagged v0.3.0 as the first official releease of the reborn library!\n\n## UPDATE December 2023\n\nI have let this project slip as I got sidetracked with a few other things, but I intend fully to return to this in the new year and polish it up/stamp it for release.\n\n## UPDATE October 2023\n\nI have finished reorganizing things, and rewrote the C++ wrapper from scratch. I have also created a test suite for the core C library (`build/baltests[.exe]`) as well as a standalone test suite for the C++ wrapper (`build/baltests++[.exe]`). Next steps: documentation. This is something I've been wrestling with–I like Doxygen, but I have found that unless you wait until you ship to write the comments, they will change over time, entropy will creep in, and sooner or later your documentation is out of sync.\n\nI want the in-IDE tooltip documentation to be available, so I will at least be writing Doxygen `@brief` descriptions for functions, types, etc. but [this MkDocs theme](https://squidfunk.github.io/mkdocs-material/) is too cool to not use. Therefore, I shall write the documentation by hand in markdown and use `mkdocs-material` to generate the static site.\n\nI am going to use an example-driven approach to documentation, because that's the kind I like. Monkey see, monkey do. Speaking of that, I would like to demonstrate a small snippet showing the extent to which libbal encapsulates and abstracts away the horrors of Berkeley Sockets.\n\n## A Little C++ Sample\n\n```cpp\n#include \u003cbal.hh\u003e\n#include \u003ciostream\u003e\n#include \u003ccstdlib\u003e\n\nusing namespace bal;\nusing namespace std;\n\nint main(int argc, char** argv)\n{\n    /* this code is in a try/catch block, but exceptions are optional. */\n    try {\n        /* RAII library initializer. As long as it stays in scope, libbal stays ready for duty. */\n        initializer balinit;\n\n        /* RAII socket (this behavior is optional, and you can create a manual init/destroy socket as well). */\n        scoped_socket client_sock {AF_INET, SOCK_STREAM, IPPROTO_TCP};\n\n        /* the socket class uses public std::function properties for event handlers, so that you can use a lambda,\n         * std::bind, or whatever. */\n        client_sock.on_connect = [](scoped_socket* sock)\n        {\n            address peer_addr;\n            sock-\u003eget_peer_addr(peer_addr);\n            address_info addr_info = peer_addr.get_address_info();\n            cout \u003c\u003c \"woo-hoo! connected to \" \u003c\u003c addr_info.get_addr() \u003c\u003c \" on port \" \u003c\u003c addr_info.get_port() \u003c\u003c endl;\n        };\n\n        client_sock.on_write = [](scoped_socket* sock)\n        {\n            auto sent = sock-\u003esend(imaginary, imaginary.size(), MSG_NOSIGNAL);\n            if (sent \u003e 0) {\n                cout \u003c\u003c \"wrote \" \u003c\u003c sent \u003c\u003c \" bytes \" \u003c\u003c endl;\n            }\n            // ...\n        };\n\n        client_sock.on_read = [](scoped_socket* sock)\n        {\n            // ...\n        };\n\n        // ... more events\n\n        /* registers client_sock to recieve asynchronous I/O callbacks to its event handlers.\n         * no need to `select` or `poll` here! */\n        client_sock.async_poll(BAL_EVT_CLIENT);\n\n        /* we can connect asynchronously now, and `on_connect` will be called when the connection is established. */\n        client_sock.connect(imaginary_host, imaginary_port);\n\n        cout \u003c\u003c \"running...\" \u003c\u003c endl;\n\n        /* for the purposes of this demo, spin the main thread while it waits for events. */\n        do {\n            bal_sleep_msec(100);\n            bal_thread_yield();\n        } while (!should_quit());\n\n        return EXIT_SUCCESS;\n    } catch (bal::exception\u0026 ex) {\n        cerr \u003c\u003c \"exception caught: \" \u003c\u003c ex.what() \u003c\u003c \"!\" \u003c\u003c endl;\n        return EXIT_FAILURE;\n    }\n}\n```\n\nThat's it! A nearly complete bare-bones TCP/IP client using libbal abstraction magic, and at this moment will compile and run on Linux, macOS, FreeBSD, and Windows.\n\nStay tuned for more, or just dig in if you are up for an undocumented challenge. -- RML\n\n## UPDATE August 2023\n\nI originally inteded to simply clean up the code, rename it, and add some documentation, but I have ended up making radical changes, including rewriting the async I/O mechanism. I'll be adding libbal to a strong CI pipeline as soon as I write a test suite.\n\nI also tossed the C++ wrapper because I only had the header; the .cpp file was AWOL. I'll be writing that from scratch using C++20 as the standard.\n\n## UPDATE July 2023\n\nSAL is now BAL. There are too many things in computing called SAL, and it's a dude's name. I'm not a huge fan of BAL, but hey, libbal. It could work.\n\nI have been in the mood to revist old projects that I wrote when I was younger, and I'm on to this one now, so I'm going to gussy it up, put a nice red dress on it (and matching lipstick) so that I can feel proud of it. Twenty years have passed since I started on this code, so hopefully it'll be 2 decades better when I'm done with it.\n\nStay tuned.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faremmell%2Flibbal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faremmell%2Flibbal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faremmell%2Flibbal/lists"}