diff --git a/compiled_starters/cpp/.codecrafters/compile.sh b/compiled_starters/cpp/.codecrafters/compile.sh new file mode 100755 index 0000000..9da226b --- /dev/null +++ b/compiled_starters/cpp/.codecrafters/compile.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake +cmake --build ./build diff --git a/compiled_starters/cpp/.codecrafters/run.sh b/compiled_starters/cpp/.codecrafters/run.sh new file mode 100755 index 0000000..3f4d6b9 --- /dev/null +++ b/compiled_starters/cpp/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec $(dirname $0)/build/kafka "$@" diff --git a/compiled_starters/cpp/.gitattributes b/compiled_starters/cpp/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/compiled_starters/cpp/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/compiled_starters/cpp/.gitignore b/compiled_starters/cpp/.gitignore new file mode 100644 index 0000000..6e9506c --- /dev/null +++ b/compiled_starters/cpp/.gitignore @@ -0,0 +1,55 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +build +vcpkg_installed \ No newline at end of file diff --git a/compiled_starters/cpp/CMakeLists.txt b/compiled_starters/cpp/CMakeLists.txt new file mode 100755 index 0000000..62bf83e --- /dev/null +++ b/compiled_starters/cpp/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.13) + +project(codecrafters-kafka) + +set(CMAKE_CXX_STANDARD 23) # Enable the C++23 standard + +file(GLOB_RECURSE SOURCE_FILES src/*.cpp src/*.hpp) + +add_executable(kafka ${SOURCE_FILES}) \ No newline at end of file diff --git a/compiled_starters/cpp/README.md b/compiled_starters/cpp/README.md new file mode 100644 index 0000000..9d8c86d --- /dev/null +++ b/compiled_starters/cpp/README.md @@ -0,0 +1,34 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/kafka.png) + +This is a starting point for C++ solutions to the +["Build Your Own Kafka" Challenge](https://codecrafters.io/challenges/kafka). + +In this challenge, you'll build a toy Kafka clone that's capable of accepting +and responding to APIVersions & Fetch API requests. You'll also learn about +encoding and decoding messages using the Kafka wire protocol. You'll also learn +about handling the network protocol, event loops, TCP sockets and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Kafka implementation is in `src/main.cpp`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `cmake` installed locally +1. Run `./your_program.sh` to run your Kafka broker, which is implemented in + `src/main.cpp`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. diff --git a/compiled_starters/cpp/codecrafters.yml b/compiled_starters/cpp/codecrafters.yml new file mode 100644 index 0000000..ad26fa0 --- /dev/null +++ b/compiled_starters/cpp/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the C++ version used to run your code +# on Codecrafters. +# +# Available versions: cpp-23 +language_pack: cpp-23 diff --git a/compiled_starters/cpp/src/main.cpp b/compiled_starters/cpp/src/main.cpp new file mode 100644 index 0000000..000d13e --- /dev/null +++ b/compiled_starters/cpp/src/main.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + // Disable output buffering + std::cout << std::unitbuf; + std::cerr << std::unitbuf; + + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + std::cerr << "Failed to create server socket: " << std::endl; + return 1; + } + + // Since the tester restarts your program quite often, setting SO_REUSEADDR + // ensures that we don't run into 'Address already in use' errors + int reuse = 1; + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { + close(server_fd); + std::cerr << "setsockopt failed: " << std::endl; + return 1; + } + + struct sockaddr_in server_addr{}; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(9092); + + if (bind(server_fd, reinterpret_cast(&server_addr), sizeof(server_addr)) != 0) { + close(server_fd); + std::cerr << "Failed to bind to port 9092" << std::endl; + return 1; + } + + int connection_backlog = 5; + if (listen(server_fd, connection_backlog) != 0) { + close(server_fd); + std::cerr << "listen failed" << std::endl; + return 1; + } + + std::cout << "Waiting for a client to connect...\n"; + + struct sockaddr_in client_addr{}; + socklen_t client_addr_len = sizeof(client_addr); + + // You can use print statements as follows for debugging, they'll be visible when running tests. + std::cerr << "Logs from your program will appear here!\n"; + + // Uncomment this block to pass the first stage + // + // int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); + // std::cout << "Client connected\n"; + // close(client_fd); + + close(server_fd); + return 0; +} \ No newline at end of file diff --git a/compiled_starters/cpp/vcpkg-configuration.json b/compiled_starters/cpp/vcpkg-configuration.json new file mode 100644 index 0000000..61d215f --- /dev/null +++ b/compiled_starters/cpp/vcpkg-configuration.json @@ -0,0 +1,14 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "c4af3593e1f1aa9e14a560a09e45ea2cb0dfd74d", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ] +} \ No newline at end of file diff --git a/compiled_starters/cpp/vcpkg.json b/compiled_starters/cpp/vcpkg.json new file mode 100644 index 0000000..f55ce3f --- /dev/null +++ b/compiled_starters/cpp/vcpkg.json @@ -0,0 +1,3 @@ +{ + "dependencies": [] +} \ No newline at end of file diff --git a/compiled_starters/cpp/your_program.sh b/compiled_starters/cpp/your_program.sh new file mode 100755 index 0000000..39ac638 --- /dev/null +++ b/compiled_starters/cpp/your_program.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake + cmake --build ./build +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec $(dirname $0)/build/kafka "$@" diff --git a/course-definition.yml b/course-definition.yml index 3323c58..2005ee3 100644 --- a/course-definition.yml +++ b/course-definition.yml @@ -15,6 +15,7 @@ short_description_md: |- completion_percentage: 15 languages: + - slug: "cpp" - slug: "gleam" - slug: "go" - slug: "java" diff --git a/dockerfiles/cpp-23.Dockerfile b/dockerfiles/cpp-23.Dockerfile new file mode 100644 index 0000000..72a774b --- /dev/null +++ b/dockerfiles/cpp-23.Dockerfile @@ -0,0 +1,39 @@ +# syntax=docker/dockerfile:1.7-labs +FROM gcc:14.2.0-bookworm + +# Ensures the container is re-built if dependency files change +ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="vcpkg.json,vcpkg-configuration.json" + +RUN apt-get update && \ + apt-get install --no-install-recommends -y zip=3.* && \ + apt-get install --no-install-recommends -y g++=4:* && \ + apt-get install --no-install-recommends -y build-essential=12.* && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# cmake is required by vcpkg +RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.30.5/cmake-3.30.5-Linux-x86_64.tar.gz && \ + tar -xzvf cmake-3.30.5-Linux-x86_64.tar.gz && \ + mv cmake-3.30.5-linux-x86_64/ /cmake + +ENV CMAKE_BIN="/cmake/bin" +ENV PATH="${CMAKE_BIN}:$PATH" + +RUN git clone https://github.com/microsoft/vcpkg.git && \ + ./vcpkg/bootstrap-vcpkg.sh -disableMetrics + +ENV VCPKG_ROOT="/vcpkg" +ENV PATH="${VCPKG_ROOT}:$PATH" + +WORKDIR /app + +# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses +COPY --exclude=.git --exclude=README.md . /app + +RUN vcpkg install --no-print-usage +RUN sed -i '1s/^/set(VCPKG_INSTALL_OPTIONS --no-print-usage)\n/' ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake + +RUN mkdir -p /app-cached +RUN if [ -d "/app/build" ]; then mv /app/build /app-cached; fi +RUN if [ -d "/app/vcpkg_installed" ]; then mv /app/vcpkg_installed /app-cached/build; fi + diff --git a/solutions/cpp/01-vi6/code/.codecrafters/compile.sh b/solutions/cpp/01-vi6/code/.codecrafters/compile.sh new file mode 100755 index 0000000..9da226b --- /dev/null +++ b/solutions/cpp/01-vi6/code/.codecrafters/compile.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake +cmake --build ./build diff --git a/solutions/cpp/01-vi6/code/.codecrafters/run.sh b/solutions/cpp/01-vi6/code/.codecrafters/run.sh new file mode 100755 index 0000000..3f4d6b9 --- /dev/null +++ b/solutions/cpp/01-vi6/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec $(dirname $0)/build/kafka "$@" diff --git a/solutions/cpp/01-vi6/code/.gitattributes b/solutions/cpp/01-vi6/code/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/solutions/cpp/01-vi6/code/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/solutions/cpp/01-vi6/code/.gitignore b/solutions/cpp/01-vi6/code/.gitignore new file mode 100644 index 0000000..6e9506c --- /dev/null +++ b/solutions/cpp/01-vi6/code/.gitignore @@ -0,0 +1,55 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +build +vcpkg_installed \ No newline at end of file diff --git a/solutions/cpp/01-vi6/code/CMakeLists.txt b/solutions/cpp/01-vi6/code/CMakeLists.txt new file mode 100755 index 0000000..62bf83e --- /dev/null +++ b/solutions/cpp/01-vi6/code/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.13) + +project(codecrafters-kafka) + +set(CMAKE_CXX_STANDARD 23) # Enable the C++23 standard + +file(GLOB_RECURSE SOURCE_FILES src/*.cpp src/*.hpp) + +add_executable(kafka ${SOURCE_FILES}) \ No newline at end of file diff --git a/solutions/cpp/01-vi6/code/README.md b/solutions/cpp/01-vi6/code/README.md new file mode 100644 index 0000000..9d8c86d --- /dev/null +++ b/solutions/cpp/01-vi6/code/README.md @@ -0,0 +1,34 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/kafka.png) + +This is a starting point for C++ solutions to the +["Build Your Own Kafka" Challenge](https://codecrafters.io/challenges/kafka). + +In this challenge, you'll build a toy Kafka clone that's capable of accepting +and responding to APIVersions & Fetch API requests. You'll also learn about +encoding and decoding messages using the Kafka wire protocol. You'll also learn +about handling the network protocol, event loops, TCP sockets and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Kafka implementation is in `src/main.cpp`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `cmake` installed locally +1. Run `./your_program.sh` to run your Kafka broker, which is implemented in + `src/main.cpp`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. diff --git a/solutions/cpp/01-vi6/code/codecrafters.yml b/solutions/cpp/01-vi6/code/codecrafters.yml new file mode 100644 index 0000000..ad26fa0 --- /dev/null +++ b/solutions/cpp/01-vi6/code/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the C++ version used to run your code +# on Codecrafters. +# +# Available versions: cpp-23 +language_pack: cpp-23 diff --git a/solutions/cpp/01-vi6/code/src/main.cpp b/solutions/cpp/01-vi6/code/src/main.cpp new file mode 100644 index 0000000..eb08e2c --- /dev/null +++ b/solutions/cpp/01-vi6/code/src/main.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + // Disable output buffering + std::cout << std::unitbuf; + std::cerr << std::unitbuf; + + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + std::cerr << "Failed to create server socket: " << std::endl; + return 1; + } + + // Since the tester restarts your program quite often, setting SO_REUSEADDR + // ensures that we don't run into 'Address already in use' errors + int reuse = 1; + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { + close(server_fd); + std::cerr << "setsockopt failed: " << std::endl; + return 1; + } + + struct sockaddr_in server_addr{}; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(9092); + + if (bind(server_fd, reinterpret_cast(&server_addr), sizeof(server_addr)) != 0) { + close(server_fd); + std::cerr << "Failed to bind to port 9092" << std::endl; + return 1; + } + + int connection_backlog = 5; + if (listen(server_fd, connection_backlog) != 0) { + close(server_fd); + std::cerr << "listen failed" << std::endl; + return 1; + } + + std::cout << "Waiting for a client to connect...\n"; + + struct sockaddr_in client_addr{}; + socklen_t client_addr_len = sizeof(client_addr); + + int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); + std::cout << "Client connected\n"; + close(client_fd); + + close(server_fd); + return 0; +} \ No newline at end of file diff --git a/solutions/cpp/01-vi6/code/vcpkg-configuration.json b/solutions/cpp/01-vi6/code/vcpkg-configuration.json new file mode 100644 index 0000000..61d215f --- /dev/null +++ b/solutions/cpp/01-vi6/code/vcpkg-configuration.json @@ -0,0 +1,14 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "c4af3593e1f1aa9e14a560a09e45ea2cb0dfd74d", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ] +} \ No newline at end of file diff --git a/solutions/cpp/01-vi6/code/vcpkg.json b/solutions/cpp/01-vi6/code/vcpkg.json new file mode 100644 index 0000000..f55ce3f --- /dev/null +++ b/solutions/cpp/01-vi6/code/vcpkg.json @@ -0,0 +1,3 @@ +{ + "dependencies": [] +} \ No newline at end of file diff --git a/solutions/cpp/01-vi6/code/your_program.sh b/solutions/cpp/01-vi6/code/your_program.sh new file mode 100755 index 0000000..39ac638 --- /dev/null +++ b/solutions/cpp/01-vi6/code/your_program.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake + cmake --build ./build +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec $(dirname $0)/build/kafka "$@" diff --git a/solutions/cpp/01-vi6/diff/src/main.cpp.diff b/solutions/cpp/01-vi6/diff/src/main.cpp.diff new file mode 100644 index 0000000..f42086c --- /dev/null +++ b/solutions/cpp/01-vi6/diff/src/main.cpp.diff @@ -0,0 +1,42 @@ +@@ -29,37 +29,32 @@ + } + + struct sockaddr_in server_addr{}; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(9092); + + if (bind(server_fd, reinterpret_cast(&server_addr), sizeof(server_addr)) != 0) { + close(server_fd); + std::cerr << "Failed to bind to port 9092" << std::endl; + return 1; + } + + int connection_backlog = 5; + if (listen(server_fd, connection_backlog) != 0) { + close(server_fd); + std::cerr << "listen failed" << std::endl; + return 1; + } + + std::cout << "Waiting for a client to connect...\n"; + + struct sockaddr_in client_addr{}; + socklen_t client_addr_len = sizeof(client_addr); + +- // You can use print statements as follows for debugging, they'll be visible when running tests. +- std::cerr << "Logs from your program will appear here!\n"; +- +- // Uncomment this block to pass the first stage +- // +- // int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); +- // std::cout << "Client connected\n"; +- // close(client_fd); ++ int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); ++ std::cout << "Client connected\n"; ++ close(client_fd); + + close(server_fd); + return 0; + } +\ No newline at end of file diff --git a/solutions/cpp/01-vi6/explanation.md b/solutions/cpp/01-vi6/explanation.md new file mode 100644 index 0000000..289f174 --- /dev/null +++ b/solutions/cpp/01-vi6/explanation.md @@ -0,0 +1,19 @@ +The entry point for your Kafka implementation is in `src/main.cpp`. + +Study and uncomment the relevant code: + +```cpp +// Uncomment this block to pass the first stage + +int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); +std::cout << "Client connected\n"; +close(client_fd); +``` + +Push your changes to pass the first stage: + +``` +git add . +git commit -m "pass 1st stage" # any msg +git push origin master +``` diff --git a/starter_templates/cpp/code/.codecrafters/compile.sh b/starter_templates/cpp/code/.codecrafters/compile.sh new file mode 100755 index 0000000..9da226b --- /dev/null +++ b/starter_templates/cpp/code/.codecrafters/compile.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake +cmake --build ./build diff --git a/starter_templates/cpp/code/.codecrafters/run.sh b/starter_templates/cpp/code/.codecrafters/run.sh new file mode 100755 index 0000000..3f4d6b9 --- /dev/null +++ b/starter_templates/cpp/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec $(dirname $0)/build/kafka "$@" diff --git a/starter_templates/cpp/code/.gitignore b/starter_templates/cpp/code/.gitignore new file mode 100644 index 0000000..6e9506c --- /dev/null +++ b/starter_templates/cpp/code/.gitignore @@ -0,0 +1,55 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +build +vcpkg_installed \ No newline at end of file diff --git a/starter_templates/cpp/code/CMakeLists.txt b/starter_templates/cpp/code/CMakeLists.txt new file mode 100755 index 0000000..62bf83e --- /dev/null +++ b/starter_templates/cpp/code/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.13) + +project(codecrafters-kafka) + +set(CMAKE_CXX_STANDARD 23) # Enable the C++23 standard + +file(GLOB_RECURSE SOURCE_FILES src/*.cpp src/*.hpp) + +add_executable(kafka ${SOURCE_FILES}) \ No newline at end of file diff --git a/starter_templates/cpp/code/src/main.cpp b/starter_templates/cpp/code/src/main.cpp new file mode 100644 index 0000000..000d13e --- /dev/null +++ b/starter_templates/cpp/code/src/main.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + // Disable output buffering + std::cout << std::unitbuf; + std::cerr << std::unitbuf; + + int server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + std::cerr << "Failed to create server socket: " << std::endl; + return 1; + } + + // Since the tester restarts your program quite often, setting SO_REUSEADDR + // ensures that we don't run into 'Address already in use' errors + int reuse = 1; + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { + close(server_fd); + std::cerr << "setsockopt failed: " << std::endl; + return 1; + } + + struct sockaddr_in server_addr{}; + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = INADDR_ANY; + server_addr.sin_port = htons(9092); + + if (bind(server_fd, reinterpret_cast(&server_addr), sizeof(server_addr)) != 0) { + close(server_fd); + std::cerr << "Failed to bind to port 9092" << std::endl; + return 1; + } + + int connection_backlog = 5; + if (listen(server_fd, connection_backlog) != 0) { + close(server_fd); + std::cerr << "listen failed" << std::endl; + return 1; + } + + std::cout << "Waiting for a client to connect...\n"; + + struct sockaddr_in client_addr{}; + socklen_t client_addr_len = sizeof(client_addr); + + // You can use print statements as follows for debugging, they'll be visible when running tests. + std::cerr << "Logs from your program will appear here!\n"; + + // Uncomment this block to pass the first stage + // + // int client_fd = accept(server_fd, reinterpret_cast(&client_addr), &client_addr_len); + // std::cout << "Client connected\n"; + // close(client_fd); + + close(server_fd); + return 0; +} \ No newline at end of file diff --git a/starter_templates/cpp/code/vcpkg-configuration.json b/starter_templates/cpp/code/vcpkg-configuration.json new file mode 100644 index 0000000..61d215f --- /dev/null +++ b/starter_templates/cpp/code/vcpkg-configuration.json @@ -0,0 +1,14 @@ +{ + "default-registry": { + "kind": "git", + "baseline": "c4af3593e1f1aa9e14a560a09e45ea2cb0dfd74d", + "repository": "https://github.com/microsoft/vcpkg" + }, + "registries": [ + { + "kind": "artifact", + "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", + "name": "microsoft" + } + ] +} \ No newline at end of file diff --git a/starter_templates/cpp/code/vcpkg.json b/starter_templates/cpp/code/vcpkg.json new file mode 100644 index 0000000..f55ce3f --- /dev/null +++ b/starter_templates/cpp/code/vcpkg.json @@ -0,0 +1,3 @@ +{ + "dependencies": [] +} \ No newline at end of file diff --git a/starter_templates/cpp/config.yml b/starter_templates/cpp/config.yml new file mode 100644 index 0000000..af5dd0e --- /dev/null +++ b/starter_templates/cpp/config.yml @@ -0,0 +1,3 @@ +attributes: + required_executable: cmake + user_editable_file: src/main.cpp