From 5c306a453784a33690ae60afa8a462e8561088e1 Mon Sep 17 00:00:00 2001 From: Ruslan Kovtun Date: Sat, 14 Feb 2026 20:40:07 +0200 Subject: [PATCH 1/3] Adds graceful shutdown using signal handler --- src/lib/net/net_serve.c | 20 +++++++++++++++++++- src/main.c | 12 ------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib/net/net_serve.c b/src/lib/net/net_serve.c index 8078045..62c8ad9 100644 --- a/src/lib/net/net_serve.c +++ b/src/lib/net/net_serve.c @@ -1,5 +1,16 @@ +#include +#include + #include "header.h" +volatile sig_atomic_t shutdown_requested = false; + +void +signal_hander([[maybe_unused]] int sig) +{ + shutdown_requested = true; +} + /** * Starts a server that listens for incoming connections on the specified host * and port. The server will accept incoming connections and pass them to the @@ -18,6 +29,12 @@ int net_serve(char* host, ProtocolHandler handle_protocol, RequestContext* context) { + struct sigaction sa = {.sa_handler = signal_hander}; + // Termination signal + sigaction(SIGTERM, &sa, nullptr); + // Interrupt from keyboard + sigaction(SIGINT, &sa, nullptr); + int port; char head[50], tail[50]; @@ -30,7 +47,7 @@ net_serve(char* host, ProtocolHandler handle_protocol, RequestContext* context) int server_socket = net_listener(head, port); printf("Serving requests on %d\n", port); - while (1) { + while (!shutdown_requested) { struct sockaddr_in client_addr; socklen_t client_addrlen = sizeof(client_addr); int client_conn = @@ -38,6 +55,7 @@ net_serve(char* host, ProtocolHandler handle_protocol, RequestContext* context) &client_addrlen); if (client_conn < 0) { + if (errno == EINTR) continue; perror("accept() failed"); close(server_socket); exit(1); diff --git a/src/main.c b/src/main.c index 3814e6e..e79937f 100644 --- a/src/main.c +++ b/src/main.c @@ -29,21 +29,9 @@ main() router_add(router, "^/404$", Error404); router_add(router, "^/static/(.*)$", Static); - /* - * Used to check for memory leaks in allocation and deallocation of - * memory - */ - // router_free(router); - // printf("Freed test router\n"); - printf("Server listening on %d\n", PORT); http.ListenAndServe(hostname, router); - /* - * TODO: This is never reached due to infinite listener that stops on - * CTRL + C - * - Need to add a way to handle graceful shut down - */ printf("\n\n\t << Graceful Shutdown >>\n\n"); router_free(router); From c27f305dd133e8e176034e8ffa0abde5a6d3e459 Mon Sep 17 00:00:00 2001 From: oduortoni Date: Wed, 18 Feb 2026 06:17:55 +0300 Subject: [PATCH 2/3] fix: slow CI workflow - remove auto-formatting in its entirety - cache dependencies - remove hurl tests in favor of curl --- .github/workflows/build-and-test.yml | 60 ++++++++++------------------ tests/integration-tests.sh | 15 ++++--- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index f0686e3..c74dc07 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,5 +1,6 @@ name: C Build and Test on: + workflow_dispatch: pull_request: push: branches: @@ -10,52 +11,35 @@ env: jobs: build-and-test: runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write - container: - image: koutoftimer/oduortoni-c-http-server-actions:latest steps: - name: Checkout repository uses: actions/checkout@v4 with: - token: ${{ secrets.PAT_TOKEN }} fetch-depth: 0 ref: ${{ github.head_ref || github.ref }} + + - name: Cache APT packages + uses: actions/cache@v4 + with: + path: /var/cache/apt/archives + key: ${{ runner.os }}-apt-${{ hashFiles('**/build-and-test.yml') }} + restore-keys: | + ${{ runner.os }}-apt- - - name: Auto-format code + - name: Cache build artifacts + uses: actions/cache@v4 + with: + path: | + bin/ + obj/ + key: ${{ runner.os }}-build-${{ hashFiles('src/**', 'Makefile') }} + restore-keys: | + ${{ runner.os }}-build- + + - name: Install dependencies run: | - set -x # Enable debug output - - git config --global --add safe.directory $PWD - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - # Run formatting - pre-commit run --all-files || true - - # Debug: show git status - echo "=== Git Status ===" - git status - echo "=== Git Diff ===" - git diff - echo "=== Porcelain ===" - git status --porcelain - - # Exit early if no changes - if [ -z "$(git status --porcelain)" ]; then - echo "✓ No formatting changes needed" - exit 0 - fi - - # Only set up git remote if we actually need to push - echo "Changes detected, setting up authentication..." - git remote set-url origin https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/${{ github.repository }}.git - - git add -A - git commit -m "style: auto-format code with clang-format [skip ci]" - git push - echo "✓ Code formatted and pushed" + sudo apt-get update + sudo apt-get install -y gcc-14 make curl - name: Build C code run: | diff --git a/tests/integration-tests.sh b/tests/integration-tests.sh index 99a181e..bc03312 100755 --- a/tests/integration-tests.sh +++ b/tests/integration-tests.sh @@ -30,15 +30,18 @@ for i in {1..25}; do fi done -# Run Hurl tests -if [ -z "$HURL" ]; then - HURL="hurl" -fi +echo "Testing routes..." -$HURL --test --variable PORT="$PORT" tests/integration-tests.hurl +curl -s "$HOST/" | grep -q "A Minimalistic C Server" || die "Home page test failed" +echo "✓ Home page works" -[ $? -ne 0 ] && die "hurl failed" +curl -s "$HOST/nonexistent" | grep -q "404" || die "404 test failed" +echo "✓ 404 handling works" + +echo "All integration tests passed" # Check for closing connection printf '' > /dev/tcp/127.0.0.1/9000 sleep 0.3 + +echo "Testing closing connection complete" From d6a37df4ae3a54a8911b473409633544ceccbbc9 Mon Sep 17 00:00:00 2001 From: oduortoni Date: Wed, 18 Feb 2026 06:30:30 +0300 Subject: [PATCH 3/3] fix(tests): add gtest installation --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index c74dc07..150895c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -39,7 +39,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y gcc-14 make curl + sudo apt-get install -y gcc-14 make curl libgtest-dev pkg-config - name: Build C code run: |