view seobeo/main.c @ 2:8a43dedbe530

[Dowa] Added HashMap and Updated Arena naming.
author June Park <parkjune1995@gmail.com>
date Wed, 24 Sep 2025 13:15:32 -0700
parents adcfad6e86fb
children 2758f5527d2b
line wrap: on
line source

/*
** server.c -- a stream socket server demo
*/

#include "seobeo/seobeo.h"

void SigchildHandler(int s)
{
  (void)s; // quiet unused variable warning

  // waitpid() might overwrite errno, so we save and restore it:
  int saved_errno = errno;

  while(waitpid(-1, NULL, WNOHANG) > 0);

  errno = saved_errno;
}


void *GetInternetaddr(struct sockaddr *sa)
{
  if (sa->sa_family == AF_INET) 
  {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }

  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

void HandleClientRequest(int client_fd)
{
  FILE *file = fopen("seobeo/index.html", "rb");
  if (!file) {
    perror("fopen");
    return;
  }

  fseek(file, 0, SEEK_END);
  size_t size = ftell(file);
  fseek(file, 0, SEEK_SET);

  char *data = malloc(size);
  fread(data, 1, size, file);
  fclose(file);

  char *header = malloc(100);
  sprintf(
    header,
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Content-Length: %zu\r\n"
    "Connection: close\r\n"
    "\r\n",
    size
  );

  send(client_fd, header, strlen(header), 0);
  ssize_t total_sent = 0;
  while (total_sent < size)
  {
    ssize_t sent = send(client_fd, data + total_sent, size - total_sent, 0);
    if (sent <= 0) break;
    total_sent += sent;
  }

  close(client_fd);
}

int main(void)
{
  int32 client_fd;
  struct sockaddr_storage client_addr; 
  socklen_t sin_size;

  char client_inet_addr[INET6_ADDRSTRLEN];

  struct sigaction sa;

  sa.sa_handler = SigchildHandler; // reap all dead processes
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_RESTART;
  if (sigaction(SIGCHLD, &sa, NULL) == -1) {
    perror("sigaction");
    exit(1);
  }
  
  int sock_fd = Seobeo_CreateSocket(1, "6969", 10);

  printf("server: waiting for connections...\n");

  while (1) 
  {
    sin_size = sizeof(client_addr);
    client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);

    if (client_fd == -1)
    {
      perror("accept");
      break;
    }

    inet_ntop(
        client_addr.ss_family,
        GetInternetaddr((struct sockaddr *)&client_addr),
        client_inet_addr, sizeof client_inet_addr);

    printf("server: got connection from %s\n", client_inet_addr);

    // Create a child process
    if (!fork())
    {
      close(sock_fd);
      HandleClientRequest(client_fd);
      exit(0);
    }

    close(client_fd);
  }

  return 0;
}