summaryrefslogtreecommitdiff
path: root/src/lib_os.c
diff options
context:
space:
mode:
authorMike Pall <mike>2009-12-08 19:46:35 +0100
committerMike Pall <mike>2009-12-08 19:46:35 +0100
commit55b16959717084884fd4a0cbae6d19e3786c20c7 (patch)
treec8a07a43c13679751ed25a9d06796e9e7b2134a6 /src/lib_os.c
downloadluajit-2.0.0-beta1.tar.gz
luajit-2.0.0-beta1.tar.bz2
luajit-2.0.0-beta1.zip
RELEASE LuaJIT-2.0.0-beta1v2.0.0-beta1
Diffstat (limited to '')
-rw-r--r--src/lib_os.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/lib_os.c b/src/lib_os.c
new file mode 100644
index 00000000..bee7216a
--- /dev/null
+++ b/src/lib_os.c
@@ -0,0 +1,249 @@
1/*
2** OS library.
3** Copyright (C) 2005-2009 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 <locale.h>
11#include <time.h>
12
13#define lib_os_c
14#define LUA_LIB
15
16#include "lua.h"
17#include "lauxlib.h"
18#include "lualib.h"
19
20#ifdef LUA_USE_POSIX
21#include <unistd.h>
22#else
23#include <stdio.h>
24#endif
25
26#include "lj_obj.h"
27#include "lj_err.h"
28#include "lj_lib.h"
29
30/* ------------------------------------------------------------------------ */
31
32#define LJLIB_MODULE_os
33
34static int os_pushresult(lua_State *L, int i, const char *filename)
35{
36 int en = errno; /* calls to Lua API may change this value */
37 if (i) {
38 setboolV(L->top-1, 1);
39 return 1;
40 } else {
41 setnilV(L->top-1);
42 lua_pushfstring(L, "%s: %s", filename, strerror(en));
43 lua_pushinteger(L, en);
44 return 3;
45 }
46}
47
48LJLIB_CF(os_execute)
49{
50 lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
51 return 1;
52}
53
54LJLIB_CF(os_remove)
55{
56 const char *filename = luaL_checkstring(L, 1);
57 return os_pushresult(L, remove(filename) == 0, filename);
58}
59
60LJLIB_CF(os_rename)
61{
62 const char *fromname = luaL_checkstring(L, 1);
63 const char *toname = luaL_checkstring(L, 2);
64 return os_pushresult(L, rename(fromname, toname) == 0, fromname);
65}
66
67LJLIB_CF(os_tmpname)
68{
69#ifdef LUA_USE_POSIX
70 char buf[15+1];
71 int fp;
72 strcpy(buf, "/tmp/lua_XXXXXX");
73 fp = mkstemp(buf);
74 if (fp != -1)
75 close(fp);
76 else
77 lj_err_caller(L, LJ_ERR_OSUNIQF);
78#else
79 char buf[L_tmpnam];
80 if (tmpnam(buf) == NULL)
81 lj_err_caller(L, LJ_ERR_OSUNIQF);
82#endif
83 lua_pushstring(L, buf);
84 return 1;
85}
86
87LJLIB_CF(os_getenv)
88{
89 lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
90 return 1;
91}
92
93LJLIB_CF(os_exit)
94{
95 exit(lj_lib_optint(L, 1, EXIT_SUCCESS));
96 return 0; /* to avoid warnings */
97}
98
99LJLIB_CF(os_clock)
100{
101 setnumV(L->top++, ((lua_Number)clock())*(1.0/(lua_Number)CLOCKS_PER_SEC));
102 return 1;
103}
104
105/* ------------------------------------------------------------------------ */
106
107static void setfield(lua_State *L, const char *key, int value)
108{
109 lua_pushinteger(L, value);
110 lua_setfield(L, -2, key);
111}
112
113static void setboolfield(lua_State *L, const char *key, int value)
114{
115 if (value < 0) /* undefined? */
116 return; /* does not set field */
117 lua_pushboolean(L, value);
118 lua_setfield(L, -2, key);
119}
120
121static int getboolfield(lua_State *L, const char *key)
122{
123 int res;
124 lua_getfield(L, -1, key);
125 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
126 lua_pop(L, 1);
127 return res;
128}
129
130static int getfield(lua_State *L, const char *key, int d)
131{
132 int res;
133 lua_getfield(L, -1, key);
134 if (lua_isnumber(L, -1)) {
135 res = (int)lua_tointeger(L, -1);
136 } else {
137 if (d < 0)
138 lj_err_callerv(L, LJ_ERR_OSDATEF, key);
139 res = d;
140 }
141 lua_pop(L, 1);
142 return res;
143}
144
145LJLIB_CF(os_date)
146{
147 const char *s = luaL_optstring(L, 1, "%c");
148 time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
149 struct tm *stm;
150 if (*s == '!') { /* UTC? */
151 stm = gmtime(&t);
152 s++; /* skip `!' */
153 } else {
154 stm = localtime(&t);
155 }
156 if (stm == NULL) { /* invalid date? */
157 setnilV(L->top-1);
158 } else if (strcmp(s, "*t") == 0) {
159 lua_createtable(L, 0, 9); /* 9 = number of fields */
160 setfield(L, "sec", stm->tm_sec);
161 setfield(L, "min", stm->tm_min);
162 setfield(L, "hour", stm->tm_hour);
163 setfield(L, "day", stm->tm_mday);
164 setfield(L, "month", stm->tm_mon+1);
165 setfield(L, "year", stm->tm_year+1900);
166 setfield(L, "wday", stm->tm_wday+1);
167 setfield(L, "yday", stm->tm_yday+1);
168 setboolfield(L, "isdst", stm->tm_isdst);
169 } else {
170 char cc[3];
171 luaL_Buffer b;
172 cc[0] = '%'; cc[2] = '\0';
173 luaL_buffinit(L, &b);
174 for (; *s; s++) {
175 if (*s != '%' || *(s + 1) == '\0') { /* no conversion specifier? */
176 luaL_addchar(&b, *s);
177 } else {
178 size_t reslen;
179 char buff[200]; /* should be big enough for any conversion result */
180 cc[1] = *(++s);
181 reslen = strftime(buff, sizeof(buff), cc, stm);
182 luaL_addlstring(&b, buff, reslen);
183 }
184 }
185 luaL_pushresult(&b);
186 }
187 return 1;
188}
189
190LJLIB_CF(os_time)
191{
192 time_t t;
193 if (lua_isnoneornil(L, 1)) { /* called without args? */
194 t = time(NULL); /* get current time */
195 } else {
196 struct tm ts;
197 luaL_checktype(L, 1, LUA_TTABLE);
198 lua_settop(L, 1); /* make sure table is at the top */
199 ts.tm_sec = getfield(L, "sec", 0);
200 ts.tm_min = getfield(L, "min", 0);
201 ts.tm_hour = getfield(L, "hour", 12);
202 ts.tm_mday = getfield(L, "day", -1);
203 ts.tm_mon = getfield(L, "month", -1) - 1;
204 ts.tm_year = getfield(L, "year", -1) - 1900;
205 ts.tm_isdst = getboolfield(L, "isdst");
206 t = mktime(&ts);
207 }
208 if (t == (time_t)(-1))
209 lua_pushnil(L);
210 else
211 lua_pushnumber(L, (lua_Number)t);
212 return 1;
213}
214
215LJLIB_CF(os_difftime)
216{
217 lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
218 (time_t)(luaL_optnumber(L, 2, (lua_Number)0))));
219 return 1;
220}
221
222/* ------------------------------------------------------------------------ */
223
224LJLIB_CF(os_setlocale)
225{
226 GCstr *s = lj_lib_optstr(L, 1);
227 const char *str = s ? strdata(s) : NULL;
228 int opt = lj_lib_checkopt(L, 2, 6,
229 "\5ctype\7numeric\4time\7collate\10monetary\1\377\3all");
230 if (opt == 0) opt = LC_CTYPE;
231 else if (opt == 1) opt = LC_NUMERIC;
232 else if (opt == 2) opt = LC_TIME;
233 else if (opt == 3) opt = LC_COLLATE;
234 else if (opt == 4) opt = LC_MONETARY;
235 else if (opt == 6) opt = LC_ALL;
236 lua_pushstring(L, setlocale(opt, str));
237 return 1;
238}
239
240/* ------------------------------------------------------------------------ */
241
242#include "lj_libdef.h"
243
244LUALIB_API int luaopen_os(lua_State *L)
245{
246 LJ_LIB_REG(L, os);
247 return 1;
248}
249