{"id":20756511,"url":"https://github.com/basiliscos/cpp-empty_port","last_synced_at":"2026-04-18T20:31:39.084Z","repository":{"id":153550122,"uuid":"82206299","full_name":"basiliscos/cpp-empty_port","owner":"basiliscos","description":"Finds empty port ","archived":false,"fork":false,"pushed_at":"2017-03-02T15:14:15.000Z","size":91,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-11T15:53:35.958Z","etag":null,"topics":["network","testing"],"latest_commit_sha":null,"homepage":null,"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/basiliscos.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":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-16T17:18:41.000Z","updated_at":"2017-02-18T13:52:08.000Z","dependencies_parsed_at":"2023-05-19T11:00:29.528Z","dependency_job_id":null,"html_url":"https://github.com/basiliscos/cpp-empty_port","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/basiliscos/cpp-empty_port","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basiliscos%2Fcpp-empty_port","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basiliscos%2Fcpp-empty_port/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basiliscos%2Fcpp-empty_port/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basiliscos%2Fcpp-empty_port/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/basiliscos","download_url":"https://codeload.github.com/basiliscos/cpp-empty_port/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basiliscos%2Fcpp-empty_port/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31984125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"ssl_error","status_checked_at":"2026-04-18T20:23:29.375Z","response_time":103,"last_error":"SSL_read: 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":["network","testing"],"created_at":"2024-11-17T09:32:51.794Z","updated_at":"2026-04-18T20:31:39.064Z","avatar_url":"https://github.com/basiliscos.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cpp-empty_port\n\nFinds empty port (C++, header-only)\n\nlinux [![Build Status](https://travis-ci.org/basiliscos/cpp-empty_port.png)](https://travis-ci.org/basiliscos/cpp-empty_port.png), windows [![Build status](https://ci.appveyor.com/api/projects/status/7lqgpi6kf8ajyd50?svg=true)](https://ci.appveyor.com/project/basiliscos/cpp-empty-port)\n\n# synopsis\n\n```cpp\n#include \u003cEmptyPort.hpp\u003e\n\nnamespace ep = empty_port;\n\n\nTEST_CASE(\"...\" ) {\n    /* get first free port */\n    auto port = ep::get_random();\n    \n    /* returns true or false */\n    ep::check_port(port);\n    \n    /* waits until port will be occupied */\n    ep::wait_port(port);\n}    \n```\n\n# API\n\n```cpp\n\n/* retrun true if port is ready for usage */\nbool check_port(const port_t port, const char *host = \"127.0.0.1\");\n\n/* returns first available empty port or throws exception */\nuint16_t get_random(const char *host = \"127.0.0.1\");\n\n/* waits until up to max_wait_ms before porta will be occupied. \nRetruns true if it is, otherwise returns false */\n\u003c\nT = Kind::TCP, typename D = std::chrono::milliseconds\u003e\nbool wait_port(const port_t port, const char *host = \"127.0.0.1\", D max_wait = D(500))\n```\n\n# Description\n\nThis tiny library mimics Perl's [Net::EmptyPort](https://metacpan.org/pod/Net::EmptyPort). The idea is that it mihgt be rather easy to launch 3rd-party services, instead of mocking them, i.e. launch **redis**\n\n```cpp\n\nnamespace ep = empty_port;\nnamespace ts = test_server;\n\n...;\n\nuint16_t port = ep::get_random();\nLOG_DEBUG(\"Using port :\" \u003c\u003c port);\n\nauto port_str = boost::lexical_cast\u003cstd::string\u003e(port);\nauto server = ts::make_server({\"redis-server\", \"--port\", port_str});\nep::wait_port(port);\n/* now it is possible to send requests for redis */\n\n```\n\nor simple http-server, quickly written in scripting language:\n\n```perl\n# app.pgsi\nmy $app = sub {\n    my $env = shift;\n    return [\n        '200',\n        [ 'Content-Type' =\u003e 'text/plain' ],\n        [ \"Hello World\" ],\n    ];\n};\n\n```\n\nand then use it in unit-tests:\n\n```cpp\n\nnamespace ep = empty_port;\nnamespace ts = test_server;\n\n...;\n\nuint16_t port = ep::get_random();\nLOG_DEBUG(\"Using port :\" \u003c\u003c port);\n\nauto port_str = boost::lexical_cast\u003cstd::string\u003e(port);\nauto server = ts::make_server({\"plackup\", \"--port\", port_str, \"../t/app.psgi\"} );\nep::wait_por(port);\nLOG_DEBUG(\"app-server is ready on port \" \u003c\u003c port_str);\n\n```\n\nThe test-server RAII is unix-specific:\n\n```cpp\n#pragma once\n\n#include \u003cmemory\u003e\n#include \u003cvector\u003e\n#include \u003cfunctional\u003e\n#include \u003cinitializer_list\u003e\n#include \u003citerator\u003e\n#include \u003cstdexcept\u003e\n\n#include \u003ccstdlib\u003e\n\n#include \u003cunistd.h\u003e\n#include \u003csys/types.h\u003e\n#include \u003csignal.h\u003e\n#include \u003cstring.h\u003e\n\nnamespace test_server {\n    struct TestServer {\n        pid_t child_pid;\n        TestServer(std::initializer_list\u003cstd::string\u003e\u0026\u0026 args) {\n            auto begin = args.begin();\n            auto end = args.end();\n\n            auto program = (*begin).c_str();\n            auto args_count = args.size();\n            const char** c_args = (const char**) std::malloc(sizeof(char*) * (args_count + 1));\n            auto it = begin;\n            std::string stringized;\n            for (auto i = 0; i \u003c args_count; i++, it++) {\n                const char* c_arg = (*it).c_str();\n                c_args[i] = c_arg;\n                stringized += \" \";\n                stringized += c_arg;\n            }\n            c_args[args_count] = NULL;\n\n\n            std::cout \u003c\u003c \"going to fork to start: \" \u003c\u003c stringized \u003c\u003c \"\\n\";\n\n            pid_t pid = fork();\n            if (pid == -1) {\n                throw std::runtime_error(\"cannot fork\");\n            } else if (pid == 0) {\n                // child\n                std::cout \u003c\u003c \"executing in child\" \u003c\u003c \"\\n\";\n                int result = execvp(program, (char* const*)c_args);\n                std::cout \u003c\u003c\"failed to execute: \" \u003c\u003c strerror(errno) \u003c\u003c \"\\n\";\n                exit(-1);\n            } else {\n                // parent\n                child_pid = pid;\n                // sleep(5);\n            }\n        }\n        ~TestServer() {\n            std::cout \u003c\u003c \"terminating child \" \u003c\u003c child_pid \u003c\u003c \"\\n\";\n            kill(child_pid, 9);\n        }\n    };\n\n\n    using result_t = std::unique_ptr\u003cTestServer\u003e;\n\n    result_t make_server(std::initializer_list\u003cstd::string\u003e\u0026\u0026 args) {\n        return std::make_unique\u003cTestServer\u003e(std::move(args));\n    }\n\n};\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasiliscos%2Fcpp-empty_port","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbasiliscos%2Fcpp-empty_port","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasiliscos%2Fcpp-empty_port/lists"}