如何冻结特定任务的时钟?

Xiè*_*léi 0 linux freeze clock

例如,

# clock-pause
# touch a
# touch b
# convert -draw `date` text_draw.gif
# clock-resume
Run Code Online (Sandbox Code Playgroud)

或者,简单地

# freeze-exec sh -c 'touch a; touch b; convert -draw `date` text_draw.gif'
Run Code Online (Sandbox Code Playgroud)

预期的结果是 和 的时间戳ab绘制到图像上的文本完全相同。

是否可以?

Mat*_*lia 5

由于我必须实施@grawity 的解决方案,我认为在这里分享它会很好:

#define _GNU_SOURCE
#include <sys/types.h>
#include <dlfcn.h>
#include <stddef.h>

/* Frozen time (usual time_t, from UNIX epoch) */
const time_t fixedTime=652789800;

/* Deprecated, thus it seems not to be present in sys/types.h */
struct timezone
{
   int tz_minuteswest;     /* minutes west of Greenwich */
   int tz_dsttime;         /* type of DST correction */
};

/* Typedef for the function ptr to the original gettimeofday */
typedef int (*gettimeofday_t)(struct timeval *tv, struct timezone *tz);

/* original gettimeofday */
gettimeofday_t gettimeofday_orig = NULL;

time_t time(time_t * t)
{
    if(t!=NULL)
        *t=fixedTime;
    return fixedTime;
}

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    if(tz!=NULL)
    {
        /* forward requests about tz to the original gettimeofday */
        if(gettimeofday_orig==NULL)
        {
            gettimeofday_orig=(gettimeofday_t) dlsym(RTLD_NEXT, "gettimeofday");
            if(gettimeofday_orig==NULL)
                return -1;
        }
        int ret=gettimeofday_orig(NULL, tz);
        if(!ret)
            return ret;
    }
    if(tv!=NULL)
    {
        tv->tv_sec=fixedTime;
        tv->tv_usec=0;
    }
    return 0;
}

int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
    (void)clk_id;
    if(tp!=NULL)
    {
        tp->tv_sec=fixedTime;
        tp->tv_nsec=0;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试:

matteo@teoxubuntu:~/cpp/detourtest$ gcc -O3 -fPIC -Wall -Wextra -shared timedetour.c -o libtimedetour.so
matteo@teoxubuntu:~/cpp/detourtest$ LD_PRELOAD=/home/matteo/cpp/detourtest/libtimedetour.so date
sab  8 set 1990, 12.30.00, CEST
Run Code Online (Sandbox Code Playgroud)