root/lib_os.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. LJLIB_CF
  2. LJLIB_CF
  3. LJLIB_CF
  4. LJLIB_CF
  5. LJLIB_CF
  6. LJLIB_CF
  7. LJLIB_CF
  8. setfield
  9. setboolfield
  10. getboolfield
  11. getfield
  12. LJLIB_CF
  13. LJLIB_CF
  14. LJLIB_CF
  15. LJLIB_CF
  16. luaopen_os

   1 /*
   2 ** OS library.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 **
   5 ** Major portions taken verbatim or adapted from the Lua interpreter.
   6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
   7 */
   8 
   9 #include <errno.h>
  10 #include <time.h>
  11 
  12 #define lib_os_c
  13 #define LUA_LIB
  14 
  15 #include "lua.h"
  16 #include "lauxlib.h"
  17 #include "lualib.h"
  18 
  19 #include "lj_obj.h"
  20 #include "lj_err.h"
  21 #include "lj_lib.h"
  22 
  23 #if LJ_TARGET_POSIX
  24 #include <unistd.h>
  25 #else
  26 #include <stdio.h>
  27 #endif
  28 
  29 #if !LJ_TARGET_PSVITA
  30 #include <locale.h>
  31 #endif
  32 
  33 /* ------------------------------------------------------------------------ */
  34 
  35 #define LJLIB_MODULE_os
  36 
  37 LJLIB_CF(os_execute)
  38 {
  39 #if LJ_NO_SYSTEM
  40 #if LJ_52
  41   errno = ENOSYS;
  42   return luaL_fileresult(L, 0, NULL);
  43 #else
  44   lua_pushinteger(L, -1);
  45   return 1;
  46 #endif
  47 #else
  48   const char *cmd = luaL_optstring(L, 1, NULL);
  49   int stat = system(cmd);
  50 #if LJ_52
  51   if (cmd)
  52     return luaL_execresult(L, stat);
  53   setboolV(L->top++, 1);
  54 #else
  55   setintV(L->top++, stat);
  56 #endif
  57   return 1;
  58 #endif
  59 }
  60 
  61 LJLIB_CF(os_remove)
  62 {
  63   const char *filename = luaL_checkstring(L, 1);
  64   return luaL_fileresult(L, remove(filename) == 0, filename);
  65 }
  66 
  67 LJLIB_CF(os_rename)
  68 {
  69   const char *fromname = luaL_checkstring(L, 1);
  70   const char *toname = luaL_checkstring(L, 2);
  71   return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
  72 }
  73 
  74 LJLIB_CF(os_tmpname)
  75 {
  76 #if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA
  77   lj_err_caller(L, LJ_ERR_OSUNIQF);
  78   return 0;
  79 #else
  80 #if LJ_TARGET_POSIX
  81   char buf[15+1];
  82   int fp;
  83   strcpy(buf, "/tmp/lua_XXXXXX");
  84   fp = mkstemp(buf);
  85   if (fp != -1)
  86     close(fp);
  87   else
  88     lj_err_caller(L, LJ_ERR_OSUNIQF);
  89 #else
  90   char buf[L_tmpnam];
  91   if (tmpnam(buf) == NULL)
  92     lj_err_caller(L, LJ_ERR_OSUNIQF);
  93 #endif
  94   lua_pushstring(L, buf);
  95   return 1;
  96 #endif
  97 }
  98 
  99 LJLIB_CF(os_getenv)
 100 {
 101 #if LJ_TARGET_CONSOLE
 102   lua_pushnil(L);
 103 #else
 104   lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
 105 #endif
 106   return 1;
 107 }
 108 
 109 LJLIB_CF(os_exit)
 110 {
 111   int status;
 112   if (L->base < L->top && tvisbool(L->base))
 113     status = boolV(L->base) ? EXIT_SUCCESS : EXIT_FAILURE;
 114   else
 115     status = lj_lib_optint(L, 1, EXIT_SUCCESS);
 116   if (L->base+1 < L->top && tvistruecond(L->base+1))
 117     lua_close(L);
 118   exit(status);
 119   return 0;  /* Unreachable. */
 120 }
 121 
 122 LJLIB_CF(os_clock)
 123 {
 124   setnumV(L->top++, ((lua_Number)clock())*(1.0/(lua_Number)CLOCKS_PER_SEC));
 125   return 1;
 126 }
 127 
 128 /* ------------------------------------------------------------------------ */
 129 
 130 static void setfield(lua_State *L, const char *key, int value)
 131 {
 132   lua_pushinteger(L, value);
 133   lua_setfield(L, -2, key);
 134 }
 135 
 136 static void setboolfield(lua_State *L, const char *key, int value)
 137 {
 138   if (value < 0)  /* undefined? */
 139     return;  /* does not set field */
 140   lua_pushboolean(L, value);
 141   lua_setfield(L, -2, key);
 142 }
 143 
 144 static int getboolfield(lua_State *L, const char *key)
 145 {
 146   int res;
 147   lua_getfield(L, -1, key);
 148   res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
 149   lua_pop(L, 1);
 150   return res;
 151 }
 152 
 153 static int getfield(lua_State *L, const char *key, int d)
 154 {
 155   int res;
 156   lua_getfield(L, -1, key);
 157   if (lua_isnumber(L, -1)) {
 158     res = (int)lua_tointeger(L, -1);
 159   } else {
 160     if (d < 0)
 161       lj_err_callerv(L, LJ_ERR_OSDATEF, key);
 162     res = d;
 163   }
 164   lua_pop(L, 1);
 165   return res;
 166 }
 167 
 168 LJLIB_CF(os_date)
 169 {
 170   const char *s = luaL_optstring(L, 1, "%c");
 171   time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
 172   struct tm *stm;
 173 #if LJ_TARGET_POSIX
 174   struct tm rtm;
 175 #endif
 176   if (*s == '!') {  /* UTC? */
 177     s++;  /* Skip '!' */
 178 #if LJ_TARGET_POSIX
 179     stm = gmtime_r(&t, &rtm);
 180 #else
 181     stm = gmtime(&t);
 182 #endif
 183   } else {
 184 #if LJ_TARGET_POSIX
 185     stm = localtime_r(&t, &rtm);
 186 #else
 187     stm = localtime(&t);
 188 #endif
 189   }
 190   if (stm == NULL) {  /* Invalid date? */
 191     setnilV(L->top-1);
 192   } else if (strcmp(s, "*t") == 0) {
 193     lua_createtable(L, 0, 9);  /* 9 = number of fields */
 194     setfield(L, "sec", stm->tm_sec);
 195     setfield(L, "min", stm->tm_min);
 196     setfield(L, "hour", stm->tm_hour);
 197     setfield(L, "day", stm->tm_mday);
 198     setfield(L, "month", stm->tm_mon+1);
 199     setfield(L, "year", stm->tm_year+1900);
 200     setfield(L, "wday", stm->tm_wday+1);
 201     setfield(L, "yday", stm->tm_yday+1);
 202     setboolfield(L, "isdst", stm->tm_isdst);
 203   } else {
 204     char cc[3];
 205     luaL_Buffer b;
 206     cc[0] = '%'; cc[2] = '\0';
 207     luaL_buffinit(L, &b);
 208     for (; *s; s++) {
 209       if (*s != '%' || *(s + 1) == '\0') {  /* No conversion specifier? */
 210         luaL_addchar(&b, *s);
 211       } else {
 212         size_t reslen;
 213         char buff[200];  /* Should be big enough for any conversion result. */
 214         cc[1] = *(++s);
 215         reslen = strftime(buff, sizeof(buff), cc, stm);
 216         luaL_addlstring(&b, buff, reslen);
 217       }
 218     }
 219     luaL_pushresult(&b);
 220   }
 221   return 1;
 222 }
 223 
 224 LJLIB_CF(os_time)
 225 {
 226   time_t t;
 227   if (lua_isnoneornil(L, 1)) {  /* called without args? */
 228     t = time(NULL);  /* get current time */
 229   } else {
 230     struct tm ts;
 231     luaL_checktype(L, 1, LUA_TTABLE);
 232     lua_settop(L, 1);  /* make sure table is at the top */
 233     ts.tm_sec = getfield(L, "sec", 0);
 234     ts.tm_min = getfield(L, "min", 0);
 235     ts.tm_hour = getfield(L, "hour", 12);
 236     ts.tm_mday = getfield(L, "day", -1);
 237     ts.tm_mon = getfield(L, "month", -1) - 1;
 238     ts.tm_year = getfield(L, "year", -1) - 1900;
 239     ts.tm_isdst = getboolfield(L, "isdst");
 240     t = mktime(&ts);
 241   }
 242   if (t == (time_t)(-1))
 243     lua_pushnil(L);
 244   else
 245     lua_pushnumber(L, (lua_Number)t);
 246   return 1;
 247 }
 248 
 249 LJLIB_CF(os_difftime)
 250 {
 251   lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
 252                              (time_t)(luaL_optnumber(L, 2, (lua_Number)0))));
 253   return 1;
 254 }
 255 
 256 /* ------------------------------------------------------------------------ */
 257 
 258 LJLIB_CF(os_setlocale)
 259 {
 260 #if LJ_TARGET_PSVITA
 261   lua_pushliteral(L, "C");
 262 #else
 263   GCstr *s = lj_lib_optstr(L, 1);
 264   const char *str = s ? strdata(s) : NULL;
 265   int opt = lj_lib_checkopt(L, 2, 6,
 266     "\5ctype\7numeric\4time\7collate\10monetary\1\377\3all");
 267   if (opt == 0) opt = LC_CTYPE;
 268   else if (opt == 1) opt = LC_NUMERIC;
 269   else if (opt == 2) opt = LC_TIME;
 270   else if (opt == 3) opt = LC_COLLATE;
 271   else if (opt == 4) opt = LC_MONETARY;
 272   else if (opt == 6) opt = LC_ALL;
 273   lua_pushstring(L, setlocale(opt, str));
 274 #endif
 275   return 1;
 276 }
 277 
 278 /* ------------------------------------------------------------------------ */
 279 
 280 #include "lj_libdef.h"
 281 
 282 LUALIB_API int luaopen_os(lua_State *L)
 283 {
 284   LJ_LIB_REG(L, LUA_OSLIBNAME, os);
 285   return 1;
 286 }
 287 

/* [<][>][^][v][top][bottom][index][help] */