递归遍历目录时C中的gmtime不一致

时间:2018-08-24 11:44:11

标签: c recursion time directory time-t

我有一个C程序,在其中使用遍历目录结构的递归函数。它接受一个toy_data.to_json() '{"GDP_Quarterly_Growth_Rate":{"-710294400000":-0.266691,"-707616000000":-0.266691,"-704937600000":-0.266691,"-702345600000":-0.206496,"-699667200000":-0.206496,"-697075200000":-0.206496,"-694396800000":1.564208,"-691718400000":1.564208,"-689212800000":1.564208,"-686534400000":1.504256}}' toy_data.resample('M', convention = 'start').mean() 变量,并从中创建一个gmtime结构。

递归dir函数来自How to recursively list directories in C on Linux?

time_t

这是运行程序时的输出。

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或2018年8月14日上午11:25:30,程序执行时为零十天。

您可以看到转换非常不一致。秒数次于执行时的实际时间。一天也要更改几次。

任何人都知道或有什么想法会导致这种情况?我已经尝试过制作一个简单的循环来转换静态1534245930而没有任何问题,所以我只能假定它有一些东西要

1 个答案:

答案 0 :(得分:2)

仔细阅读time(7)gmtime(3)

请注意,gmtime不是reentrant,因为它返回某些静态数据的地址。您需要gmtime_r(因为您的traversedir函数是递归的),并且应该使用本地struct tm automatic variable

如此

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

然后t将指向call stack上的mytm(而不是某些静态数据)。

您还应该使用strftime(3)(同样,将足够大的缓冲区声明为自动变量,或者使用一些堆分配的缓冲区)。

您可能也对nftw(3)stat(2)感兴趣。

也请阅读How to debug small programs