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