diff options
author | rsiddharth <s@ricketyspace.net> | 2019-08-24 19:26:17 -0400 |
---|---|---|
committer | rsiddharth <s@ricketyspace.net> | 2020-04-17 20:56:33 -0400 |
commit | 0c5b08ea58f88252e950ecaf40125a22b79fa83c (patch) | |
tree | 89508d0e0d6afc6cb6379bde9139777af5341160 /nserver/bin/statserve.c |
Add nserver.
For now it contains only "statserve".
Diffstat (limited to 'nserver/bin/statserve.c')
-rw-r--r-- | nserver/bin/statserve.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/nserver/bin/statserve.c b/nserver/bin/statserve.c new file mode 100644 index 0000000..d62622a --- /dev/null +++ b/nserver/bin/statserve.c @@ -0,0 +1,118 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +#include <dbg.h> + +#define PORT "7899" +#define BACKLOG 10 + +int echo(int sock, char *buf, int len) +{ + int bytes = 0; + + bytes = send(sock, buf, len, 0); + check(bytes >= 0, "statserv: send failed"); + + return bytes; + error: + return -1; +} + +void serve(int sock) +{ + int rc = 0; + int buf_len = 1000; + char buf[buf_len]; + ssize_t bytes; + + do { + bytes = recv(sock, buf, buf_len, 0); + check(bytes >= 0, "statserv: recv failed"); + + if (bytes < 1) { + break; + } + + rc = echo(sock, buf, bytes); + check(rc != -1, "statserv: echo failed"); + } while(1); + + rc = close(sock); + check(rc == 0, "statserv: close failed"); + + exit(0); + error: + rc = close(sock); + check(rc == 0, "statserv: close failed"); + exit(1); +} + +int main(void) +{ + int rc = 0; + int sockfd_s = 0, sockfd_c = 0; + struct addrinfo hints; + struct addrinfo *servinfo = NULL; + struct sockaddr sockaddr_c; + socklen_t sockaddr_c_len; + pid_t pidc; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + rc = getaddrinfo(NULL, PORT, &hints, &servinfo); + check(rc == 0, "statserve: getaddrinfo failed"); + + sockfd_s = socket(servinfo->ai_family, servinfo->ai_socktype, + servinfo->ai_protocol); + check(sockfd_s != 0, "statserve: socket failed"); + + rc = bind(sockfd_s, servinfo->ai_addr, servinfo->ai_addrlen); + check(rc == 0, "statserve: bind failed"); + + rc = listen(sockfd_s, BACKLOG); + check(rc == 0, "statserve: listen failed"); + + do { + printf("Waiting for connection...\n"); + sockfd_c = accept(sockfd_s, &sockaddr_c, &sockaddr_c_len); + + pidc = fork(); + check(pidc != -1, "statserve: fork failed"); + + if (pidc == 0) { + serve(sockfd_c); + } + + rc = close(sockfd_c); + check(rc == 0, "statserv: close failed"); + } while(1); + + // Clean up. + freeaddrinfo(servinfo); + + rc = close(sockfd_s); + check(rc == 0, "statserv: close failed"); + + return 0; + + error: + if (servinfo) + freeaddrinfo(servinfo); + if (sockfd_s) { + rc = close(sockfd_s); + check(rc == 0, "statserv: close failed"); + } + if (sockfd_c) { + rc = close(sockfd_c); + check(rc == 0, "statserv: close failed"); + } + + return -1; +} |