Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.81 KB | None | 0 0
  1. enum { BUF_SIZE = 256 };
  2.  
  3. ssize_t write2(int fd, char * buf, size_t size) {
  4.     ssize_t tmp = write(fd, buf, size);
  5.     if (tmp <= 0) {
  6.         exit(0);
  7.     }
  8.     return tmp;
  9. }
  10.  
  11. ssize_t read2(int fd, char * buf, size_t size) {
  12.     ssize_t tmp = read(fd, buf, size);
  13.     if (tmp <= 0) {
  14.         exit(0);
  15.     }
  16.     return tmp;
  17. }
  18.  
  19. int add_overflow(unsigned a, unsigned b) {
  20.     int tmp;
  21.     return ((int)a != a) || ((int)b != b) || __builtin_sadd_overflow(a, b, &tmp);
  22. }
  23.  
  24. void ignore_handler(int sig) {
  25.     ;
  26. }
  27.  
  28. void usr1_handler(int sig) {
  29.     exit(0);
  30. }
  31.  
  32. void term_handler(int sig) {
  33.     kill(-getpid(), SIGUSR1);
  34.     while (wait(NULL) > 0) { ; }
  35.     exit(0);
  36. };
  37.  
  38. void process(int fd, const char * KEY, unsigned serial) {
  39.     char buf[BUF_SIZE];
  40.     strcpy(buf, KEY);
  41.     strncat(buf, "\r\n", 3);
  42.     write2(fd, buf, strlen(buf));
  43.     sprintf(buf, "%u\r\n", serial);
  44.     write2(fd, buf, strlen(buf));
  45.     ssize_t size = read2(fd, buf, sizeof(buf));
  46.     buf[size] = '\0';
  47.     unsigned max = strtoul(buf, NULL, 10);
  48.     write2(fd, buf, size);
  49.     unsigned num;
  50.     while (1) {
  51.         size = read2(fd, buf, sizeof(buf));
  52.         buf[size] = '\0';
  53.         num = strtoul(buf, NULL, 10);
  54.         if (num > max || add_overflow(num, serial)) {
  55.             strcpy(buf, "-1\r\n");
  56.             write2(fd, buf, 4);
  57.             close(fd);
  58.             return;
  59.         }
  60.         sprintf(buf, "%u\r\n", num + serial);
  61.         write2(fd, buf, strlen(buf));
  62.     }
  63. }
  64.  
  65. int main(int argc, char ** argv) {
  66.     signal(SIGTERM, term_handler);
  67.     signal(SIGUSR1, ignore_handler);
  68.     if (argc < 3) {
  69.         return 1;
  70.     }
  71.     int fd = socket(PF_INET, SOCK_STREAM, 0);
  72.     if (fd < 0) {
  73.         perror("socket\n");
  74.         return 1;
  75.     }
  76.     // magic
  77.     int val = 1;
  78.     setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
  79.     setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
  80.  
  81.     struct sockaddr_in s1;
  82.     s1.sin_family = AF_INET;
  83.     s1.sin_port = htons(strtol(argv[1], NULL, 10));
  84.     s1.sin_addr.s_addr = INADDR_ANY;
  85.     int r = bind(fd, (struct sockaddr*) &s1, sizeof(s1));
  86.     if (r < 0) {
  87.         perror("bind\n");
  88.         return 1;
  89.     }
  90.     // magic again
  91.     listen(fd, 5);
  92.  
  93.     unsigned serial = 1;
  94.  
  95.     while (1) {
  96.         while (waitpid(-1, NULL, WNOHANG) > 0) { ; }
  97.         struct sockaddr_in s2;
  98.         socklen_t slen = sizeof(s2);
  99.         int fd2 = accept(fd, (struct sockaddr *) &s2, &slen);
  100.         if (fd2 < 0) {
  101.             continue;
  102.         }
  103.         pid_t pid = fork();
  104.         if (pid < 0) {
  105.             close(fd2);
  106.             continue;
  107.         }
  108.         if (pid == 0) {
  109.             signal(SIGUSR1, usr1_handler);
  110.             process(fd2, argv[2], serial);
  111.             exit(0);
  112.         }
  113.         close(fd2);
  114.         ++serial;
  115.     }
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement