#include "async.h"

void
echo_write(int fd, strbuf buf)
{
  int n = buf.tosuio()->output(fd);

  if(n < 0)
    fatal << "write\n";

  // still stuff to write: don't disable writability callback
  if(buf.tosuio()->resid())
    return;

  fdcb(fd, selwrite, 0);
}



void
echo_read(int fd)
{
  strbuf buf;
  int n = buf.tosuio()->input(fd);

  if(n < 0)
    fatal << "read\n";

  if(n == 0) {
    fdcb(fd, selread, 0);
    close(fd);
    return;
  };

  fdcb(fd, selwrite, wrap(echo_write, fd, buf));
}

void
accept_connection(int fd)
{
  struct sockaddr_in sin;
  unsigned sinlen = sizeof(sin);

  int cs = accept(fd, (struct sockaddr *) &sin, &sinlen);
  if (cs >= 0) {
    warn << "accepted connection. file descriptor = " << cs << "\n";
  } else if (errno != EAGAIN)
    fatal << "accept; errno = " << errno << "\n";

  fdcb(cs, selread, wrap(echo_read, cs));
}
  

int
main(int argc, char *argv[]) 
{
  if(argc < 2)
    fatal << "usage: inetsocket port\n";

  int fd = inetsocket(SOCK_STREAM, atoi(argv[1]));
  if (fd < 0)
    fatal << "inetsocket\n";
  make_async(fd);
  if (listen(fd, 5) < 0)
    fatal << "listen\n";

  fdcb(fd, selread, wrap(accept_connection, fd));

  amain();
}
