/*
* Copyright ©2026 Naomi Alterman. All rights reserved. Permission is
* hereby granted to students registered for University of Washington
* CSE 333 for use solely during Spring Quarter 2026 for purposes of
* the course. No other use, copying, distribution, or modification
* is permitted without prior written consent. Copyrights for
* third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the
* author.
*/
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "SocketUtil.h"
#define BUFSIZE 1024
using std::cerr;
using std::endl;
using std::cout;
// Prints usage information about this program and exits with EXIT_FAILURE.
void Usage(char* progname);
// Listen and accept a connection on a socket, then
// read data from the socket and write it to stdout.
int main(int argc, char** argv) {
if (argc != 2) {
Usage(argv[0]);
}
// Create the listening socket.
int sock_family, listen_fd;
listen_fd = Listen(argv[1], &sock_family);
if (listen_fd == -1) {
cerr << "Failed to created listening socket on port "
<< argv[1] << endl;
Usage(argv[0]);
}
// Wait for a client to arrive.
int client_fd;
while (1) {
struct sockaddr_storage caddr;
socklen_t caddr_len = sizeof(caddr);
client_fd = accept(listen_fd,
reinterpret_cast<struct sockaddr*>(&caddr),
&caddr_len);
if (client_fd < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
cerr << "Failure on accept: " << strerror(errno) << endl;
close(listen_fd);
Usage(argv[0]);
}
break;
}
// Loop, reading data from client_fd and writing it to stdout.
while (1) {
unsigned char buf[BUFSIZE];
int res = WrappedRead(client_fd, buf, BUFSIZE);
if (res == 0) // connection closed
break;
if (res < 0) { // error
close(client_fd);
close(listen_fd);
return EXIT_FAILURE;
}
std::string out(reinterpret_cast<char*>(buf), res);
cout << out;
}
close(client_fd);
close(listen_fd);
return EXIT_SUCCESS;
}
void Usage(char* progname) {
cerr << "usage: " << progname << " port" << endl;
exit(EXIT_FAILURE);
}