auxsystem.c /size: 4176 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# include "luametatex.h"
6
7/*tex This code is taken from the \LUA\ socket library: |timeout.c|. */
8
9# ifdef _WIN32
10
11    double aux_get_current_time(void) {
12        FILETIME ft;
13        double t;
14        GetSystemTimeAsFileTime(&ft);
15        /* Windows file time (time since January 1, 1601 (UTC)) */
16        t  = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
17        /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
18        return (t - 11644473600.0);
19    }
20
21# else
22
23    double aux_get_current_time(void) {
24        struct timeval v;
25        gettimeofday(&v, (struct timezone *) NULL);
26        /* Unix Epoch time (time since January 1, 1970 (UTC)) */
27        return v.tv_sec + v.tv_usec/1.0e6;
28    }
29
30# endif
31
32void aux_set_run_time(void)
33{
34    lmt_main_state.start_time = aux_get_current_time();
35}
36
37double aux_get_run_time(void)
38{
39    return aux_get_current_time() - lmt_main_state.start_time;
40}
41
42/*tex
43
44    In order to avoid all kind of time code in the backend code we use a function. The start time
45    can be overloaded in several ways:
46
47    \startitemize[n]
48        \startitem
49            By setting the environmment variable |SOURCE_DATE_EPOCH|. This will influence the \PDF\
50            timestamp and \PDF\ id that is derived from the time. This variable is consulted when
51            the kpse library is enabled which is analogue to other properties.
52        \stopitem
53        \startitem
54            By setting the |texconfig.start_time| variable (as with other variables we use the
55            internal name there). This has the same effect as (1) and is provided for when kpse is
56            not used to set these variables or when an overloaded is wanted. This is analogue to
57            other properties.
58        \stopitem
59    \stopitemize
60
61    To some extend a cleaner solution would be to have a flag that disables all variable data in
62    one go (like filenames and so) but we just follow the method implemented in pdftex where
63    primitives are used to disable it.
64
65*/
66
67static int start_time = -1; /*tex This will move to one of the structs. */
68
69static int aux_get_start_time(void) {
70    if (start_time < 0) {
71        start_time = (int) time((time_t *) NULL);
72    }
73    return start_time;
74}
75
76/*tex
77
78    This one is used to fetch a value from texconfig which can also be used to set properties.
79    This might come in handy when one has other ways to get date info in the \PDF\ file.
80
81*/
82
83void aux_set_start_time(int s) {
84    if (s >= 0) {
85        start_time = s ;
86    }
87}
88
89/*tex
90
91    All our interrupt handler has to do is set \TEX's global variable |interrupt|; then they
92    will do everything needed.
93
94*/
95
96# ifdef _WIN32
97
98    /* Win32 doesn't set SIGINT ... */
99
100    static BOOL WINAPI catch_interrupt(DWORD arg)
101    {
102        switch (arg) {
103            case CTRL_C_EVENT:
104            case CTRL_BREAK_EVENT:
105                aux_quit_the_program();
106                return 1;
107            default:
108                /*tex No need to set interrupt as we are exiting anyway. */
109                return 0;
110        }
111    }
112
113    void aux_set_interrupt_handler(void)
114    {
115        SetConsoleCtrlHandler(catch_interrupt, TRUE);
116    }
117
118# else
119
120    /* static RETSIGTYPE catch_interrupt(int arg) */
121
122    static void catch_interrupt(int arg)
123    {
124        (void) arg;
125        aux_quit_the_program();
126        (void) signal(SIGINT, catch_interrupt);
127    }
128
129    void aux_set_interrupt_handler(void)
130    {
131        /* RETSIGTYPE (*old_handler) (int); */
132        void (*old_handler) (int);
133        old_handler = signal(SIGINT, catch_interrupt);
134        if (old_handler != SIG_DFL) {
135            signal(SIGINT, old_handler);
136        }
137    }
138
139# endif
140
141void aux_get_date_and_time(int *minutes, int *day, int *month, int *year, int *utc)
142{
143    time_t myclock = aux_get_start_time();
144    struct tm *tmptr ;
145    if (*utc) {
146        tmptr = gmtime(&myclock);
147    } else {
148        tmptr = localtime(&myclock);
149    }
150    *minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
151    *day = tmptr->tm_mday;
152    *month = tmptr->tm_mon + 1;
153    *year = tmptr->tm_year + 1900;
154 /* set_interrupt_handler(); */
155}
156