personal/hw2/httpserver.c
/*
 * Opens a TCP stream socket on all interfaces with port number PORTNO. Saves
 * the fd number of the server socket in *socket_number. For each accepted
 * connection, calls request_handler with the accepted fd number.
 */
Opens a TCP stream socket on all interfaces with port number PORTNO. Saves
the fd number of the server socket in *socket_number. For each accepted
connection, calls request_handler with the accepted fd number.
Opens a TCP stream socket on all interfaces with port number PORTNO . Saves the fd number of the server socket in * socket_number . For each accepted connection calls request_handler with the accepted fd number .
void serve_forever(int* socket_number, void (*request_handler)(int))
{
  struct sockaddr_in server_address, client_address;
  size_t client_address_length = sizeof(client_address);
  int client_socket_number;
  pid_t pid;
  *socket_number = socket(PF_INET, SOCK_STREAM, 0);
  if (*socket_number == -1) {
    fprintf(stderr, "Failed to create a new socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }
  int socket_option = 1;
  if (setsockopt(*socket_number, SOL_SOCKET, SO_REUSEADDR, &socket_option,
        sizeof(socket_option)) == -1) {
    fprintf(stderr, "Failed to set socket options: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }
  memset(&server_address, 0, sizeof(server_address));
  server_address.sin_family = AF_INET;
  server_address.sin_addr.s_addr = INADDR_ANY;
  server_address.sin_port = htons(server_port);
  if (bind(*socket_number, (struct sockaddr*) &server_address,
        sizeof(server_address)) == -1) {
    fprintf(stderr, "Failed to bind on socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }
  if (listen(*socket_number, 1024) == -1) {
    fprintf(stderr, "Failed to listen on socket: error %d: %s\n", errno, strerror(errno));
    exit(errno);
  }
  printf("Listening on port %d...\n", server_port);
  while (1) {
    client_socket_number = accept(*socket_number, (struct sockaddr*) &client_address,
        (socklen_t*) &client_address_length);
    if (client_socket_number < 0) {
      fprintf(stderr, "Error accepting socket: error %d: %s\n", errno, strerror(errno));
      continue;
    }
    printf("Accepted connection from %s on port %d\n", inet_ntoa(client_address.sin_addr),
        client_address.sin_port);
    pid = fork();
    if (pid > 0) {
      close(client_socket_number);
    } else if (pid == 0) {
      signal(SIGINT, SIG_DFL); 
      close(*socket_number);
      request_handler(client_socket_number);
      close(client_socket_number);
      exit(EXIT_SUCCESS);
    } else {
      fprintf(stderr, "Failed to fork child: error %d: %s\n", errno, strerror(errno));
      exit(errno);
    }
  }
  close(*socket_number);
}
void serve_forever ( int * socket_number , void ( * request_handler ) ( int ) ) { struct sockaddr_in server_address , client_address ; size_t client_address_length = sizeof ( client_address ) ; int client_socket_number ; pid_t pid ; * socket_number = socket ( PF_INET , SOCK_STREAM , 0 ) ; if ( * socket_number == -1 ) { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; exit ( errno ) ; } int socket_option = 1 ; if ( setsockopt ( * socket_number , SOL_SOCKET , SO_REUSEADDR , & socket_option , sizeof ( socket_option ) ) == -1 ) { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; exit ( errno ) ; } memset ( & server_address , 0 , sizeof ( server_address ) ) ; server_address . sin_family = AF_INET ; server_address . sin_addr . s_addr = INADDR_ANY ; server_address . sin_port = htons ( server_port ) ; if ( bind ( * socket_number , ( struct sockaddr * ) & server_address , sizeof ( server_address ) ) == -1 ) { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; exit ( errno ) ; } if ( listen ( * socket_number , 1024 ) == -1 ) { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; exit ( errno ) ; } printf ( " \n " , server_port ) ; while ( 1 ) { client_socket_number = accept ( * socket_number , ( struct sockaddr * ) & client_address , ( socklen_t * ) & client_address_length ) ; if ( client_socket_number < 0 ) { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; continue ; } printf ( " \n " , inet_ntoa ( client_address . sin_addr ) , client_address . sin_port ) ; pid = fork ( ) ; if ( pid > 0 ) { close ( client_socket_number ) ; } else if ( pid == 0 ) { signal ( SIGINT , SIG_DFL ) ; close ( * socket_number ) ; request_handler ( client_socket_number ) ; close ( client_socket_number ) ; exit ( EXIT_SUCCESS ) ; } else { fprintf ( stderr , " \n " , errno , strerror ( errno ) ) ; exit ( errno ) ; } } close ( * socket_number ) ; }
Opens a TCP stream socket on all interfaces with port number PORTNO.
Opens a TCP stream socket on all interfaces with port number PORTNO .
// Un-register signal handler (only parent should have it)