#include #include #include #include #include #include #include /* TODO * - should check for close() errors, theoretically */ int make_server_socket(const struct sockaddr_in *sa, int backlog) { const int one = 1; int server_socket; server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server_socket == -1) { perror("socket"); exit(1); } if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) { perror("setsockopt SO_REUSEADDR"); exit(1); } if (bind(server_socket, (struct sockaddr *) sa, sizeof(*sa)) != 0) { perror("bind"); exit(1); } if (listen(server_socket, backlog) != 0) { perror("listen"); exit(1); } return server_socket; } int main(int argc, char *const argv[]) { int server_socket; struct sockaddr_in sa; int port; char *const *new_argv; int option; int listen_backlog = 20; while ((option = getopt(argc, argv, "b:")) != -1) { switch (option) { case 'b': listen_backlog = atoi(optarg); break; } } if (optind + 2 >= argc) { fprintf(stderr, "Usage: %s [-b listen_backlog] host port command...\n", argv[0]); exit(1); } sa.sin_family = AF_INET; if (inet_aton(argv[optind], &sa.sin_addr) == 0) { fprintf(stderr, "Bad IP address: %s\n", argv[optind]); exit(1); } port = atoi(argv[optind + 1]); if (port <= 0) { fputs("Bad port number", stderr); exit(1); } sa.sin_port = htons(port); server_socket = make_server_socket(&sa, listen_backlog); if (dup2(server_socket, STDIN_FILENO) == -1) { perror("dup2"); exit(1); } close(server_socket); new_argv = argv + optind + 2; execvp(*new_argv, new_argv); perror("execvp"); exit(1); }