/* a simple lua interface for fetching the UNIX time
* it uses the process's alarm() to update the time, so
* it's not especially accurate or nice, but it does
* for our purposes, and it means we don't have to
* faff around updating it all the time,
*/
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
static time_t ourTime = -1;
#ifdef SIGNALTIME
#include <signal.h>
static void signalHandler(int signo) {
if (signo == SIGALRM) {
ourTime = time(NULL);
alarm(2);
}
}
#endif
static int lua_epoch_time(lua_State *L) {
#ifndef SIGNALTIME
if( lua_gettop(L) != 0 ) ourTime = -1;
else if( ourTime == -1 ) time(&ourTime);
#endif
lua_settop(L, 0);
lua_pushnumber(L, ourTime);
return 1;
}
/* Mostly cribbed from io_date in liolib.c of Lua4.0 */
static int ltime_date(lua_State *L) {
char b[256];
const char *s = luaL_opt_string(L, 1, "%c");
struct tm *stm;
#ifndef SIGNALTIME
if (ourTime == -1) time(&ourTime);
#endif
stm = localtime(&ourTime);
if (strftime(b, sizeof(b), s, stm))
lua_pushstring(L, b);
else
lua_error(L, "invalid `date' format");
return 1;
}
void ltime_register(lua_State *L) {
#ifdef SIGNALTIME
struct sigaction sa_new;
sa_new.sa_handler = signalHandler;
sigemptyset(&sa_new.sa_mask);
sigaddset(&sa_new.sa_mask, SIGALRM);
sa_new.sa_flags = 0;
sigaction(SIGALRM, &sa_new, 0);
signalHandler(SIGALRM);
alarm(2);
#endif
lua_pushcclosure(L, lua_epoch_time, 0);
lua_setglobal(L, "getSecs");
lua_pushcclosure(L, ltime_date, 0);
lua_setglobal(L, "safeDate" );
}