Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 1 │ #include <sys/types.h>
- 2 │ #include <sys/socket.h>
- 3 │ #include <netdb.h>
- 4 │ #include <stdio.h>
- 5 │ #include <stdlib.h>
- 6 │ #include <netinet/in.h>
- 7 │ #include <netdb.h>
- 8 │ #include <arpa/inet.h>
- 9 │ #include <string.h>
- 10 │ #include <errno.h>
- 11 │ #include <sys/wait.h>
- 12 │ #include <signal.h>
- 13 │ #include <unistd.h>
- 14 │ #include <limits.h>
- 15 │
- 16 │ volatile sig_atomic_t term_triggered = 0;
- 17 │
- 18 │ void handler1(int s) {
- 19 │ term_triggered = 1;
- 20 │ }
- 21 │
- 22 │ void handler2(int s) {
- 23 │ _exit(0);
- 24 │ }
- 25 │
- 26 │ int main(int argc, char* argv[]) {
- 27 │ sigset_t sigset, empty;
- 28 │ sigemptyset(&sigset);
- 29 │ sigemptyset(&empty);
- 30 │ sigaddset(&sigset, SIGTERM);
- 31 │ sigprocmask(SIG_BLOCK, &sigset, NULL);
- 32 │ sigaction(SIGTERM, &(struct sigaction) { .sa_handler=handler1 }, NULL);
- 33 │
- 34 │ // fprintf(stderr, "my_pid: %d\n", getpid());
- 35 │
- 36 │ if (argc != 3) {
- 37 │ return 1;
- 38 │ }
- 39 │
- 40 │ int sfd;
- 41 │ if ((sfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
- 42 │ perror("socket");
- 43 │ return 1;
- 44 │ }
- 45 │
- 46 │ int sopt = 1;
- 47 │ if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &sopt, sizeof(sopt)) < 0) {
- 48 │ close(sfd);
- 49 │ perror("setsockopt SO_REUSEADDR");
- 50 │ return 1;
- 51 │ }
- 52 │ if (setsockopt(sfd, SOL_SOCKET, SO_REUSEPORT, &sopt, sizeof(sopt)) < 0) {
- 53 │ close(sfd);
- 54 │ perror("setsockopt SO_REUSEPORT");
- 55 │ return 1;
- 56 │ }
- 57 │
- 58 │ struct sockaddr_in addr;
- 59 │ addr.sin_family = AF_INET;
- 60 │ addr.sin_port = htons(strtol(argv[1], NULL, 10));
- 61 │ addr.sin_addr.s_addr = INADDR_ANY;
- 62 │
- 63 │ if (bind(sfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- 64 │ close(sfd);
- 65 │ perror("bind");
- 66 │ return 1;
- 67 │ }
- 68 │
- 69 │ if (listen(sfd, 5) < 0) {
- 70 │ close(sfd);
- 71 │ perror("listen");
- 72 │ return 1;
- 73 │ }
- 74 │
- 75 │ int SERIAL = 1;
- 76 │ while (!term_triggered) {
- 77 │ while (waitpid(-1, NULL, WNOHANG) > 0);
- 78 │
- 79 │ struct sockaddr_in new_addr;
- 80 │ socklen_t new_len = sizeof(struct sockaddr_in);
- 81 │ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
- 82 │ int afd = accept(sfd, (struct sockaddr*)&new_addr, &new_len);
- 83 │ sigprocmask(SIG_BLOCK, &sigset, NULL);
- 84 │ if (afd < 0) {
- 85 │ if (term_triggered) break;
- 86 │ close(sfd);
- 87 │ perror("accept");
- 88 │ return 1;
- 89 │ }
- 90 │ if (term_triggered) {
- 91 │ close(afd);
- 92 │ break;
- 93 │ }
- 94 │ int pid = fork();
- 95 │ if (pid < 0) {
- 96 │ if (term_triggered) {
- 97 │ close(afd);
- 98 │ break;
- 99 │ }
- 100 │ perror("fork");
- 101 │ } else if (!pid) {
- 102 │ close(sfd);
- 103 │ sigaction(SIGTERM, &(struct sigaction) { .sa_handler=handler2 }, NULL);
- 104 │ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
- 105 │
- 106 │ FILE* s_in = fdopen(dup(afd), "r");
- 107 │ FILE* s_out = fdopen(afd, "w");
- 108 │
- 109 │ if (fprintf(s_out, "%s\r\n", argv[2]) < 0
- 110 │ || fprintf(s_out, "%d\r\n", SERIAL) < 0 || fflush(s_out) < 0) {
- 111 │ fclose(s_in), fclose(s_out);
- 112 │ return 0;
- 113 │ }
- 114 │
- 115 │ int MAX;
- 116 │ if (fscanf(s_in, "%d", &MAX) <= 0) {
- 117 │ fclose(s_in), fclose(s_out);
- 118 │ return 0;
- 119 │ }
- 120 │ if (fprintf(s_out, "%d\r\n", MAX) < 0 || fflush(s_out) < 0) {
- 121 │ fclose(s_in), fclose(s_out);
- 122 │ return 0;
- 123 │ }
- 124 │
- 125 │ int NUM;
- 126 │ int sval = 0;
- 127 │ while ((sval = fscanf(s_in, "%d", &NUM)) != EOF && sval > 0) {
- 128 │ if (NUM > MAX || NUM > INT_MAX - SERIAL) {
- 129 │ if (fprintf(s_out, "-1\r\n") < 0 || fflush(s_out) < 0) {
- 130 │ fclose(s_in), fclose(s_out);
- 131 │ return 0;
- 132 │ }
- 133 │ break;
- 134 │ }
- 135 │ if (fprintf(s_out, "%d\r\n", NUM + SERIAL) < 0 || fflush(s_out) < 0) {
- 136 │ fclose(s_in), fclose(s_out);
- 137 │ return 0;
- 138 │ }
- 139 │ }
- 140 │ fclose(s_in);
- 141 │ fclose(s_out);
- 142 │ _exit(0);
- 143 │ } else {
- 144 │ ++SERIAL;
- 145 │ }
- 146 │ close(afd);
- 147 │ }
- 148 │ close(sfd);
- 149 │ kill(0, SIGTERM);
- 150 │ while (wait(NULL) > 0);
- 151 │ }
- ───────┴────────
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement