How do these 2 string buffers interact? Why does the internal logger buffer append to the buffer i dynamically allocate in main
12:07 26 Nov 2025

So, for context, I have started writing a small HTTP-Server for learning purposes. Currently, I have 2 modules: server, and Logger. The server module uses the logger I wrote internally for logging messages. I will add the 2 modules here as follows: server.h + server.c, then Logger.h and Logger.c

struct server {
  int socket_fd;
  struct addrinfo *serv_info;
  char port[6];
  char ip_str[INET6_ADDRSTRLEN];
  int backlog;
};

server *server_init(server *serv, char *addr, char *port) {
  int status = 0;
  struct addrinfo hints = {0};

  if (serv == NULL)
    return NULL;

  if (port == NULL) {
    log_msg(COMMUNICATION, ERROR, "Please provide a non-null port to bind to");
    return NULL;
  }

  hints.ai_socktype = SOCK_STREAM;
  hints.ai_family = AF_UNSPEC;
  hints.ai_flags = AI_PASSIVE;

  status = getaddrinfo(addr, port, &hints, &serv->serv_info);
  if (status != 0) {
    log_msg(COMMUNICATION, ERROR, "GetAddrInfo error: [%d]", status); 
    return NULL;
  }

  struct addrinfo *p;
  for (p = serv->serv_info; p != NULL; p = p->ai_next) {
    serv->socket_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if (serv->socket_fd < 0) continue;

    int yes = 1;
    setsockopt(serv->socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

    status = bind(serv->socket_fd, p->ai_addr, p->ai_addrlen);
    if (status < 0) {
      log_msg(COMMUNICATION, ERROR, "Could not bind to port: [%s]", port);
      goto err_cleanup;
    }

    /* finish up initializing the structure */
    serv->backlog = BACKLOG;
    memcpy(serv->port, port, strlen(port));
    serv->port[strlen(port)] = '\0';
    inet_pton(
        serv->serv_info->ai_family,
        serv->serv_info->ai_addr->sa_data,
        serv->ip_str
      ); 
    
    break;
  }

  if (p == NULL) {
    log_msg(COMMUNICATION, ERROR, "Failed to bind to any socket");
    goto err_cleanup;
  }
   
  status = listen(serv->socket_fd, serv->backlog);
  if (status < 0) {
    log_msg(COMMUNICATION, ERROR, "Failed to listen on socket");
    goto err_cleanup;
  }

  return serv;

err_cleanup:
  freeaddrinfo(serv->serv_info);
  return NULL;
}


And for the Logger:


#include 

typedef enum {
  INFORMATION,
  DEBUG,
  WARNING, 
  ERROR,
  CRITICAL
} eLogLevel;

#define LOG_SUBS_COUNT 4

typedef enum {
  COMMUNICATION,
  DISPLAY,
  SYSTEM,
  SENSOR
} eLogSubSystem;

typedef struct s_log_struct {
  eLogLevel subs_levels[LOG_SUBS_COUNT];
  int fd; 
  int enabled;

  void (*output_func)(const char *msg); 
} Logger; 

void log_msg(eLogSubSystem system, eLogLevel level, const char *fmt, ...);

void log_msg(eLogSubSystem system, eLogLevel level, const char *fmt, ...) {
    pthread_mutex_lock(&lock);

    if (!gLogData || !gLogData->enabled || level < gLogData->subs_levels[system]) {
        pthread_mutex_unlock(&lock);
        return;
    }

    char buffer[1024]; 
    int offset = 0;

    rfc8601_timespec(buffer, 64); 
    offset = strlen(buffer);

    offset += snprintf(buffer + offset, sizeof(buffer) - offset, 
                       "[%s][%s] ", 
                       subsystem_to_str(system), 
                       level_to_str(level));

    if (offset < sizeof(buffer) - 1) {
        va_list args;
        va_start(args, fmt);
        offset += vsnprintf(buffer + offset, sizeof(buffer) - offset, fmt, args);
        va_end(args);
    }

    if (offset >= sizeof(buffer)) {
        offset = sizeof(buffer) - 2;
    }
    buffer[offset] = '\n';
    buffer[offset + 1] = '\0';

    gLogData->output_func(buffer);

    pthread_mutex_unlock(&lock);
}

I have included the only 2 relevant functions, I believe

The thing is: on the line:

  if (port == NULL) {
    log_msg(COMMUNICATION, ERROR, "Please provide a non-null port to bind to");
    return NULL;
  }

When I send back a dummy GET-response in my main:

    client_fd = accept(
        server.socket_fd,
        (struct sockaddr *) &client_addr,
        &client_size
      );
    if (client_fd < 0) {
      log_msg(COMMUNICATION, DEBUG, "Could not accept client");
      continue;
    }

    log_msg(COMMUNICATION, DEBUG, "Accepted client: [%d]", client_fd);
    response = "HTTP/1.0 200 OK \r\n"
               "\r\n"
               "Hello world\n";
    write(client_fd, response, 256);
    close(client_fd);

The output comes as:

HTTP/1.0 200 OK

Hello world Please provide a non-null port to bind tot\Llh8,Lh(|h(x0xd|^C

Now, I know that I need to write the exact amount of characters I have in the response, that is not the question. The question is why does the log_msg get appeneded to the end of the response buffer? How do the 2 interact?

c string sockets logging file-descriptor