#include #include #include #include #include #include #include #include #include #include volatile int alive = 1; void sigterm(int s) { printf("%d: Sigterm received...\n", getpid()); alive = 0; return; } void sigint(int s) { printf("%d: Sigint received...\n", getpid()); alive = 0; return; } void *client(void *sockvoid) { int cfd = (int)sockvoid; printf("Client thread started\n"); pthread_detach(pthread_self()); while(write(cfd, "Goodbye.\r\n", strlen("Goodbye.\r\n")) > 0) usleep(500000); printf("Shutting down child.\n"); shutdown(cfd, 2); close(cfd); pthread_exit(0); } void *start_loop(void *arg) { struct sockaddr_in sa; int sfd, tmp; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sfd = socket(AF_INET, SOCK_STREAM, 0); bind(sfd, (struct sockaddr *)&sa, sizeof(sa)); listen(sfd, 20); tmp = sizeof(sa); getsockname(sfd, (struct sockaddr *)&sa, &tmp); printf("Bound to: %d\n", ntohs(sa.sin_port)); while(alive) { int cfd, socklen; struct sockaddr_in csa; pthread_t client_thread; printf("Alive...\n"); socklen = sizeof(csa); cfd = accept(sfd, (struct sockaddr *)&csa, &socklen); printf("Accept received: %d\n", cfd); if(cfd < 0) { printf("Error return: %d with errno %d (%s)\n", cfd, errno, strerror(errno)); } pthread_create(&client_thread, NULL, client, (void *)cfd); } printf("Done, alive cleared.\n"); close(sfd); return NULL; } int main(int argc, char **argv) { void *retval; pthread_t child; struct sigaction sig; memset(&sig, 0, sizeof(sig)); sig.sa_handler = sigterm; sigaction(SIGTERM, &sig, NULL); sig.sa_handler = sigint; sigaction(SIGINT, &sig, NULL); printf("Creating child...\n"); pthread_create(&child, NULL, start_loop, NULL); printf("Attaching to child...\n"); pthread_join(child, &retval); printf("Child exited.\n"); exit(1); }