Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- enum { BUF_SIZE = 256 };
- ssize_t write2(int fd, char * buf, size_t size) {
- ssize_t tmp = write(fd, buf, size);
- if (tmp <= 0) {
- exit(0);
- }
- return tmp;
- }
- ssize_t read2(int fd, char * buf, size_t size) {
- ssize_t tmp = read(fd, buf, size);
- if (tmp <= 0) {
- exit(0);
- }
- return tmp;
- }
- int add_overflow(unsigned a, unsigned b) {
- int tmp;
- return ((int)a != a) || ((int)b != b) || __builtin_sadd_overflow(a, b, &tmp);
- }
- void ignore_handler(int sig) {
- ;
- }
- void usr1_handler(int sig) {
- exit(0);
- }
- void term_handler(int sig) {
- kill(-getpid(), SIGUSR1);
- while (wait(NULL) > 0) { ; }
- exit(0);
- };
- void process(int fd, const char * KEY, unsigned serial) {
- char buf[BUF_SIZE];
- strcpy(buf, KEY);
- strncat(buf, "\r\n", 3);
- write2(fd, buf, strlen(buf));
- sprintf(buf, "%u\r\n", serial);
- write2(fd, buf, strlen(buf));
- ssize_t size = read2(fd, buf, sizeof(buf));
- buf[size] = '\0';
- unsigned max = strtoul(buf, NULL, 10);
- write2(fd, buf, size);
- unsigned num;
- while (1) {
- size = read2(fd, buf, sizeof(buf));
- buf[size] = '\0';
- num = strtoul(buf, NULL, 10);
- if (num > max || add_overflow(num, serial)) {
- strcpy(buf, "-1\r\n");
- write2(fd, buf, 4);
- close(fd);
- return;
- }
- sprintf(buf, "%u\r\n", num + serial);
- write2(fd, buf, strlen(buf));
- }
- }
- int main(int argc, char ** argv) {
- signal(SIGTERM, term_handler);
- signal(SIGUSR1, ignore_handler);
- if (argc < 3) {
- return 1;
- }
- int fd = socket(PF_INET, SOCK_STREAM, 0);
- if (fd < 0) {
- perror("socket\n");
- return 1;
- }
- // magic
- int val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
- setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
- struct sockaddr_in s1;
- s1.sin_family = AF_INET;
- s1.sin_port = htons(strtol(argv[1], NULL, 10));
- s1.sin_addr.s_addr = INADDR_ANY;
- int r = bind(fd, (struct sockaddr*) &s1, sizeof(s1));
- if (r < 0) {
- perror("bind\n");
- return 1;
- }
- // magic again
- listen(fd, 5);
- unsigned serial = 1;
- while (1) {
- while (waitpid(-1, NULL, WNOHANG) > 0) { ; }
- struct sockaddr_in s2;
- socklen_t slen = sizeof(s2);
- int fd2 = accept(fd, (struct sockaddr *) &s2, &slen);
- if (fd2 < 0) {
- continue;
- }
- pid_t pid = fork();
- if (pid < 0) {
- close(fd2);
- continue;
- }
- if (pid == 0) {
- signal(SIGUSR1, usr1_handler);
- process(fd2, argv[2], serial);
- exit(0);
- }
- close(fd2);
- ++serial;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement