Untitled

mail@pastecode.io avatar
unknown
c_cpp
7 months ago
5.3 kB
4
Indexable
Never
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#ifndef countof
#define countof(x)      (sizeof( x ) / sizeof( x[0] ))
#endif
#define SELF_NAME       "hlgenerator"
static size_t arrsz(const char **arr);
const char *schemes[] = {
        "http://",
        "https://",
        "ftp://",
        "news://",
        "foobar://",
        "data:",
        "foo:",
        "",
};
const char *users[] = {
        "john:doe@",
        "smith@",
        "123456@",
        ""
};
const char *domains[] = {
        "gosuslugi.ru",
        "ietf.org",
        "москва.рф",
        ""
};
const char *ports[] = {
        ":8080",
        ":[80]",
        "[:80]",
        ":",
        ""
};
const char *paths[] = {
        "/",
        "/foo",
        "/foo/",
        "/foo/bar",
        "/foo/bar/",
        ""
};

const char *queries[] = {
        "?foo=bar&bar=buz",
        "?foo=bar&",
        "?foo=bar",
        "?foo=",
        "?foo",
        "?",
        ""
};
const char *anchors[] = {
        "#foo%20bar",
        "#foo%20",
        "#%20foo",
        "#foo",
        "#",
        ""
};
const char **sources[] = {
        schemes,
        users,
        domains,
        ports,
        paths,
        queries,
        anchors
};
size_t
arrsz(const char **arr) {
        size_t  n = 0;
        do {
                n++;
        } while (arr[n][0] != '\0');
        return ++n;
}
void
generate(int from, int to, int* status) {
        size_t idx[countof(sources)], i, j, t;
        char buf[1024];
        for (i = from; t < to; i++) {
                t = i;
                buf[0] = '\0';
                for (j = 0; j < countof(sources); j++) {
                        idx[j] = t % arrsz(sources[j]);
                        if (strlcat(buf, sources[j][idx[j]], sizeof(buf)) >= sizeof(buf)) {
                                fprintf(stderr, "internal buffer was too small\n");
                                *status = 1;
                                return;
                        }
                        t /= arrsz(sources[j]);
                }
                puts(buf);
        }
        *status = 0;
}
int
main(int argc, char** argv) {
        size_t idx[countof(sources)];
        int forksCount, status;
        pid_t* forks, pid;
        // Получить доступное количество ядер
        forksCount = sysconf(_SC_NPROCESSORS_ONLN);
        fprintf(stderr, "Доступно ядер: %d\n", forksCount);
        // Выделение памяти под массив индексов процессов
        forks = malloc(forksCount * sizeof(pid_t));
        if (forks == NULL) {
                fprintf(stderr, "Memory wrong");
                return 1;
        }
        int nvariants = 1; // Количество возможных url
        for (size_t i = 0; i < countof(sources); i++) {
                nvariants *= arrsz(sources[i]);
        }
        int from = 0;
        int to = nvariants;
        // Если один процесс
        if (forksCount == 1) {
                generate(from, to, &status);
                free(forks);
                return status;
        }
        // Получаем разбиение
        int dividedBy = (nvariants + forksCount - 1) / forksCount;
        fprintf(stderr, "Разделенно на %d частей\n", dividedBy);
        // Цикл по всем процессам
        for (size_t i = 0; i < forksCount; i++) {
                // Создаем дочерний процесс
                pid = fork();
                if(pid < 0) {
                        free(forks);
                        return 1;
                }
                // Если 0, то мы в дочерном процессе
                if(pid == 0) {
                        from = i * dividedBy;
                        to = from + dividedBy;
                        if (to > nvariants) {
                                to = nvariants;
                        }
                        fprintf(stderr, "Запускаю процесс №%d: от %d до %d\n", getpid(), from, to);
                        generate(from, to, &status);
                        return status;
                }
                // Присваиваем индекс процессу
                forks[i] = pid;

        }
        for (size_t i = 0; i < forksCount; i++) {
                int fork_status;
                // Ждем пока процесс закончится
                waitpid(forks[i], &fork_status, 0);
                fprintf(stderr, "Процесс %d закончил работу. СТАТУС: %d\n", forks[i],
                                WEXITSTATUS(fork_status));
                status |= WEXITSTATUS(fork_status);
        }
        fprintf(stderr, "Создано процессов: %d\n", forksCount);
        fprintf(stderr, "Все работы %d\n", nvariants);
        fprintf(stderr, "Все работы на один процесс %d\n", dividedBy);
        free(forks);
        return status;
}
Leave a Comment