Несовместимый gmtime в C при рекурсивном обходе каталогов - PullRequest
0 голосов
/ 24 августа 2018

У меня есть программа на C, где я использую рекурсивную функцию, которая пересекает структуру каталогов.Он берет переменную time_t и создает из нее структуру gmtime.

Рекурсивная функция dir из Как рекурсивно выводить список каталогов в C в Linux?

void traversedir(time_t cutoff, const char* name, int indent)
{
    if (indent > 9)
        return;

    DIR* dir;
    struct dirent* entry;

    if (!(dir = opendir(name)))
        return;

    struct tm *t = gmtime(&cutoff);
    printf("%d-%d-%d %d:%d:%d (%lld)\n", (1900 + t->tm_year), (t->tm_mon + 1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, (long long) cutoff);
    sleep(1);  // only for debugging

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (entry->d_name[0] == '.' && !isValidNumber(entry->d_name))
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);

            ...

            traversedir(cutoff, path, indent + 2);
        }
    }
    closedir(dir);
}

void imageCleanup()
{
    time_t cutoff = (time(NULL) - (86400 * 10));
    do {
        printf("Cutoff: %lld\n", (long long) cutoff);
        traversedir(cutoff, "/path/to/dir", 0);
        sleep(2);
        cutoff += 3600;
    } while (!available_storage() && cutoff < time(NULL));
}

Это вывод при запуске программы.

Cutoff: 1534245930
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:31 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:33 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:35 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:38 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:43 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:52 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:54 (1534245930)
2018-8-14 11:25:55 (1534245930)
2018-8-24 11:25:56 (1534245930)
2018-8-14 11:25:30 (1534245930)
2018-8-24 11:25:58 (1534245930)

time_t, из которого преобразована структура, находится в скобках.Это постоянно 1534245930 или 14 августа 2018 г. 11:25:30, то есть минус десять дней на выполнение программы.

Вы видите, что преобразование довольно противоречиво.Несколько раз секунды следуют за фактическим временем на момент выполнения.День меняется также несколько раз.

Кто-нибудь знает или имеет представление, что может вызвать это?Я попытался просто сделать простой цикл, который без проблем конвертирует статический time_t, поэтому я могу только предположить, что в нем есть что-то для

1 Ответ

0 голосов
/ 24 августа 2018

Внимательно прочитайте time (7) и gmtime (3) .

Обратите внимание, что gmtime не reentrant с момента его возвращенияадрес некоторых статических данных.Вы хотите gmtime_r (поскольку ваша traversedir функция является рекурсивной) и должны использовать локальную struct tm автоматическую переменную .

, поэтому

struct tm mytm;
struct tm *t = gmtime_r(&cutoff, &mytm);

Тогда t будет указывать на mytm в стеке вызовов (не на некоторые статические данные).

Вы также должны использовать strftime (3) (снова сдостаточно большой буфер, объявленный как автоматическая переменная, или некоторый выделенный из кучи буфер).

Вас также могут заинтересовать nftw (3) и stat (2) .

Читайте также Как отлаживать небольшие программы .

...