Use include <cstring> and std::memcpy etc
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "server.hpp" // Need this for releaseBackToServer implementation
|
#include "server.hpp" // Need this for releaseBackToServer implementation
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ ConnectionRegistry::~ConnectionRegistry() {
|
|||||||
|
|
||||||
void ConnectionRegistry::store(int fd, std::unique_ptr<Connection> connection) {
|
void ConnectionRegistry::store(int fd, std::unique_ptr<Connection> connection) {
|
||||||
if (fd < 0 || static_cast<size_t>(fd) >= max_fds_) {
|
if (fd < 0 || static_cast<size_t>(fd) >= max_fds_) {
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
// Release ownership from unique_ptr and store raw pointer
|
// Release ownership from unique_ptr and store raw pointer
|
||||||
connections_[fd].store(connection.release(), std::memory_order_release);
|
connections_[fd].store(connection.release(), std::memory_order_release);
|
||||||
@@ -55,7 +55,7 @@ void ConnectionRegistry::store(int fd, std::unique_ptr<Connection> connection) {
|
|||||||
|
|
||||||
std::unique_ptr<Connection> ConnectionRegistry::remove(int fd) {
|
std::unique_ptr<Connection> ConnectionRegistry::remove(int fd) {
|
||||||
if (fd < 0 || static_cast<size_t>(fd) >= max_fds_) {
|
if (fd < 0 || static_cast<size_t>(fd) >= max_fds_) {
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
return std::unique_ptr<Connection>(
|
return std::unique_ptr<Connection>(
|
||||||
connections_[fd].exchange(nullptr, std::memory_order_acquire));
|
connections_[fd].exchange(nullptr, std::memory_order_acquire));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
%{
|
%{
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
%}
|
%}
|
||||||
%define hash-function-name hash_json_token
|
%define hash-function-name hash_json_token
|
||||||
%define lookup-function-name lookup_json_token
|
%define lookup-function-name lookup_json_token
|
||||||
|
|||||||
15
src/main.cpp
15
src/main.cpp
@@ -6,6 +6,7 @@
|
|||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
#include <cstring>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -44,7 +45,7 @@ std::vector<int> create_listen_sockets(const weaseldb::Config &config) {
|
|||||||
unlink(config.server.unix_socket_path.c_str());
|
unlink(config.server.unix_socket_path.c_str());
|
||||||
|
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
memset(&addr, 0, sizeof(addr));
|
std::memset(&addr, 0, sizeof(addr));
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
|
|
||||||
if (config.server.unix_socket_path.length() >= sizeof(addr.sun_path)) {
|
if (config.server.unix_socket_path.length() >= sizeof(addr.sun_path)) {
|
||||||
@@ -52,7 +53,7 @@ std::vector<int> create_listen_sockets(const weaseldb::Config &config) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(addr.sun_path, config.server.unix_socket_path.c_str(),
|
std::strncpy(addr.sun_path, config.server.unix_socket_path.c_str(),
|
||||||
sizeof(addr.sun_path) - 1);
|
sizeof(addr.sun_path) - 1);
|
||||||
|
|
||||||
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
|
||||||
@@ -74,7 +75,7 @@ std::vector<int> create_listen_sockets(const weaseldb::Config &config) {
|
|||||||
struct addrinfo *result, *rp;
|
struct addrinfo *result, *rp;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
std::memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
|
||||||
hints.ai_socktype = SOCK_STREAM; /* stream socket */
|
hints.ai_socktype = SOCK_STREAM; /* stream socket */
|
||||||
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
|
||||||
@@ -86,7 +87,7 @@ std::vector<int> create_listen_sockets(const weaseldb::Config &config) {
|
|||||||
s = getaddrinfo(config.server.bind_address.c_str(),
|
s = getaddrinfo(config.server.bind_address.c_str(),
|
||||||
std::to_string(config.server.port).c_str(), &hints, &result);
|
std::to_string(config.server.port).c_str(), &hints, &result);
|
||||||
if (s != 0) {
|
if (s != 0) {
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
|
std::fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,9 +255,9 @@ int main(int argc, char *argv[]) {
|
|||||||
g_server = server.get();
|
g_server = server.get();
|
||||||
|
|
||||||
// Setup signal handling
|
// Setup signal handling
|
||||||
signal(SIGPIPE, SIG_IGN);
|
std::signal(SIGPIPE, SIG_IGN);
|
||||||
signal(SIGTERM, signal_handler);
|
std::signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
std::signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
std::cout << "Starting WeaselDB HTTP server..." << std::endl;
|
std::cout << "Starting WeaselDB HTTP server..." << std::endl;
|
||||||
server->run();
|
server->run();
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ void Server::shutdown() {
|
|||||||
// Write single byte to avoid partial write complexity
|
// Write single byte to avoid partial write complexity
|
||||||
while (write(shutdown_pipe_[1], &val, 1) == -1) {
|
while (write(shutdown_pipe_[1], &val, 1) == -1) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
abort(); // graceful shutdown didn't work. Let's go ungraceful.
|
std::abort(); // graceful shutdown didn't work. Let's go ungraceful.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,7 @@ void Server::start_io_threads(std::vector<std::thread> &threads) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
perror("epoll_wait");
|
perror("epoll_wait");
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
ready_listen_fds.clear(); // Clear from previous iteration
|
ready_listen_fds.clear(); // Clear from previous iteration
|
||||||
@@ -384,7 +384,7 @@ void Server::start_io_threads(std::vector<std::thread> &threads) {
|
|||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
perror("accept4");
|
perror("accept4");
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check connection limit
|
// Check connection limit
|
||||||
|
|||||||
@@ -344,10 +344,10 @@ public:
|
|||||||
// Violating preconditions results in program termination via abort().
|
// Violating preconditions results in program termination via abort().
|
||||||
[[nodiscard]] ProducerGuard push(uint32_t const size, bool block) {
|
[[nodiscard]] ProducerGuard push(uint32_t const size, bool block) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
if (size > slot_count) {
|
if (size > slot_count) {
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
// Reserve a slot to construct an item, but don't publish to consumer yet
|
// Reserve a slot to construct an item, but don't publish to consumer yet
|
||||||
uint32_t slot;
|
uint32_t slot;
|
||||||
|
|||||||
33
style.md
33
style.md
@@ -22,6 +22,39 @@ This document describes the C++ coding style used in the WeaselDB project. These
|
|||||||
- Use modern C++ features: RAII, move semantics, constexpr, concepts where appropriate
|
- Use modern C++ features: RAII, move semantics, constexpr, concepts where appropriate
|
||||||
- Prefer standard library containers and algorithms over custom implementations
|
- Prefer standard library containers and algorithms over custom implementations
|
||||||
|
|
||||||
|
### C Library Functions and Headers
|
||||||
|
- **Always use std:: prefixed versions** of C library functions for consistency and clarity
|
||||||
|
- **Use C++ style headers** (`<cstring>`, `<cstdlib>`, etc.) instead of C style headers (`<string.h>`, `<stdlib.h>`, etc.)
|
||||||
|
- This applies to all standard libc functions: `std::abort()`, `std::fprintf()`, `std::free()`, `std::memcpy()`, `std::strlen()`, `std::strncpy()`, `std::memset()`, `std::signal()`, etc.
|
||||||
|
- Exception: Functions with no std:: equivalent (e.g., `perror()`, `gai_strerror()`) and system-specific headers (e.g., `<unistd.h>`, `<fcntl.h>`)
|
||||||
|
```cpp
|
||||||
|
// Preferred - C++ style
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <csignal>
|
||||||
|
std::abort();
|
||||||
|
std::fprintf(stderr, "Error message\n");
|
||||||
|
std::free(ptr);
|
||||||
|
std::memcpy(dest, src, size);
|
||||||
|
std::strlen(str);
|
||||||
|
std::strncpy(dest, src, n);
|
||||||
|
std::memset(ptr, value, size);
|
||||||
|
std::signal(SIGTERM, handler);
|
||||||
|
|
||||||
|
// Avoid - C style
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
abort();
|
||||||
|
fprintf(stderr, "Error message\n");
|
||||||
|
free(ptr);
|
||||||
|
memcpy(dest, src, size);
|
||||||
|
strlen(str);
|
||||||
|
strncpy(dest, src, n);
|
||||||
|
memset(ptr, value, size);
|
||||||
|
signal(SIGTERM, handler);
|
||||||
|
```
|
||||||
|
|
||||||
### Data Types
|
### Data Types
|
||||||
- **Almost always signed** - prefer `int`, `int64_t`, `size_t` over unsigned types except for:
|
- **Almost always signed** - prefer `int`, `int64_t`, `size_t` over unsigned types except for:
|
||||||
- Bit manipulation operations
|
- Bit manipulation operations
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "connection.hpp"
|
#include "connection.hpp"
|
||||||
#include "perfetto_categories.hpp"
|
#include "perfetto_categories.hpp"
|
||||||
#include "server.hpp"
|
#include "server.hpp"
|
||||||
|
#include <cstring>
|
||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -71,9 +72,9 @@ TEST_CASE(
|
|||||||
const char *test_message = "Hello, World!";
|
const char *test_message = "Hello, World!";
|
||||||
ssize_t bytes_written;
|
ssize_t bytes_written;
|
||||||
do {
|
do {
|
||||||
bytes_written = write(client_fd, test_message, strlen(test_message));
|
bytes_written = write(client_fd, test_message, std::strlen(test_message));
|
||||||
} while (bytes_written == -1 && errno == EINTR);
|
} while (bytes_written == -1 && errno == EINTR);
|
||||||
REQUIRE(bytes_written == strlen(test_message));
|
REQUIRE(bytes_written == std::strlen(test_message));
|
||||||
|
|
||||||
// Read the echoed response
|
// Read the echoed response
|
||||||
char buffer[1024] = {0};
|
char buffer[1024] = {0};
|
||||||
@@ -84,7 +85,7 @@ TEST_CASE(
|
|||||||
if (bytes_read == -1) {
|
if (bytes_read == -1) {
|
||||||
perror("read failed");
|
perror("read failed");
|
||||||
}
|
}
|
||||||
REQUIRE(bytes_read == strlen(test_message));
|
REQUIRE(bytes_read == std::strlen(test_message));
|
||||||
|
|
||||||
// Verify we got back exactly what we sent
|
// Verify we got back exactly what we sent
|
||||||
CHECK(std::string(buffer, bytes_read) == std::string(test_message));
|
CHECK(std::string(buffer, bytes_read) == std::string(test_message));
|
||||||
@@ -93,7 +94,7 @@ TEST_CASE(
|
|||||||
int e = close(client_fd);
|
int e = close(client_fd);
|
||||||
if (e == -1 && errno != EINTR) {
|
if (e == -1 && errno != EINTR) {
|
||||||
perror("close client_fd");
|
perror("close client_fd");
|
||||||
abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
server->shutdown();
|
server->shutdown();
|
||||||
server_thread.join();
|
server_thread.join();
|
||||||
|
|||||||
Reference in New Issue
Block a user