File: | home/bhubbard/working/src/ceph/src/lua/src/loslib.c |
Warning: | line 274, column 24 Access to field 'tm_sec' results in a dereference of a null pointer (loaded from variable 'stm') |
[?] Use j/k keys for keyboard navigation
1 | /* | |||
2 | ** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp $ | |||
3 | ** Standard Operating System library | |||
4 | ** See Copyright Notice in lua.h | |||
5 | */ | |||
6 | ||||
7 | #define loslib_c | |||
8 | #define LUA_LIB | |||
9 | ||||
10 | #include "lprefix.h" | |||
11 | ||||
12 | ||||
13 | #include <errno(*__errno_location ()).h> | |||
14 | #include <locale.h> | |||
15 | #include <stdlib.h> | |||
16 | #include <string.h> | |||
17 | #include <time.h> | |||
18 | ||||
19 | #include "lua.h" | |||
20 | ||||
21 | #include "lauxlib.h" | |||
22 | #include "lualib.h" | |||
23 | ||||
24 | ||||
25 | /* | |||
26 | ** {================================================================== | |||
27 | ** list of valid conversion specifiers for the 'strftime' function | |||
28 | ** =================================================================== | |||
29 | */ | |||
30 | #if !defined(LUA_STRFTIMEOPTIONS{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", "E", "cCxXyY", "O", "deHImMSuUVwWy" }) /* { */ | |||
31 | ||||
32 | #if defined(LUA_USE_C89) | |||
33 | #define LUA_STRFTIMEOPTIONS{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", "E", "cCxXyY", "O", "deHImMSuUVwWy" } { "aAbBcdHIjmMpSUwWxXyYz%", "" } | |||
34 | #else /* C99 specification */ | |||
35 | #define LUA_STRFTIMEOPTIONS{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", "E", "cCxXyY", "O", "deHImMSuUVwWy" } \ | |||
36 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \ | |||
37 | "E", "cCxXyY", \ | |||
38 | "O", "deHImMSuUVwWy" } | |||
39 | #endif | |||
40 | ||||
41 | #endif /* } */ | |||
42 | /* }================================================================== */ | |||
43 | ||||
44 | ||||
45 | /* | |||
46 | ** {================================================================== | |||
47 | ** Configuration for time-related stuff | |||
48 | ** =================================================================== | |||
49 | */ | |||
50 | ||||
51 | #if !defined(l_time_t) /* { */ | |||
52 | /* | |||
53 | ** type to represent time_t in Lua | |||
54 | */ | |||
55 | #define l_timetlua_Integer lua_Integer | |||
56 | #define l_pushtime(L,t)lua_pushinteger(L,(lua_Integer)(t)) lua_pushinteger(L,(lua_Integer)(t)) | |||
57 | ||||
58 | static time_t l_checktime (lua_State *L, int arg) { | |||
59 | lua_Integer t = luaL_checkinteger(L, arg); | |||
60 | luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds")((void)(((time_t)t == t) || luaL_argerror(L, (arg), ("time out-of-bounds" )))); | |||
61 | return (time_t)t; | |||
62 | } | |||
63 | ||||
64 | #endif /* } */ | |||
65 | ||||
66 | ||||
67 | #if !defined(l_gmtime) /* { */ | |||
68 | /* | |||
69 | ** By default, Lua uses gmtime/localtime, except when POSIX is available, | |||
70 | ** where it uses gmtime_r/localtime_r | |||
71 | */ | |||
72 | ||||
73 | #if defined(LUA_USE_POSIX) /* { */ | |||
74 | ||||
75 | #define l_gmtime(t,r)gmtime_r(t,r) gmtime_r(t,r) | |||
76 | #define l_localtime(t,r)localtime_r(t,r) localtime_r(t,r) | |||
77 | ||||
78 | #else /* }{ */ | |||
79 | ||||
80 | /* ISO C definitions */ | |||
81 | #define l_gmtime(t,r)gmtime_r(t,r) ((void)(r)->tm_sec, gmtime(t)) | |||
82 | #define l_localtime(t,r)localtime_r(t,r) ((void)(r)->tm_sec, localtime(t)) | |||
83 | ||||
84 | #endif /* } */ | |||
85 | ||||
86 | #endif /* } */ | |||
87 | ||||
88 | /* }================================================================== */ | |||
89 | ||||
90 | ||||
91 | /* | |||
92 | ** {================================================================== | |||
93 | ** Configuration for 'tmpnam': | |||
94 | ** By default, Lua uses tmpnam except when POSIX is available, where | |||
95 | ** it uses mkstemp. | |||
96 | ** =================================================================== | |||
97 | */ | |||
98 | #if !defined(lua_tmpnam) /* { */ | |||
99 | ||||
100 | #if defined(LUA_USE_POSIX) /* { */ | |||
101 | ||||
102 | #include <unistd.h> | |||
103 | ||||
104 | #define LUA_TMPNAMBUFSIZE32 32 | |||
105 | ||||
106 | #if !defined(LUA_TMPNAMTEMPLATE"/tmp/lua_XXXXXX") | |||
107 | #define LUA_TMPNAMTEMPLATE"/tmp/lua_XXXXXX" "/tmp/lua_XXXXXX" | |||
108 | #endif | |||
109 | ||||
110 | #define lua_tmpnam(b,e){ strcpy(b, "/tmp/lua_XXXXXX"); e = mkstemp(b); if (e != -1) close (e); e = (e == -1); } { \ | |||
111 | strcpy(b, LUA_TMPNAMTEMPLATE"/tmp/lua_XXXXXX"); \ | |||
112 | e = mkstemp(b); \ | |||
113 | if (e != -1) close(e); \ | |||
114 | e = (e == -1); } | |||
115 | ||||
116 | #else /* }{ */ | |||
117 | ||||
118 | /* ISO C definitions */ | |||
119 | #define LUA_TMPNAMBUFSIZE32 L_tmpnam20 | |||
120 | #define lua_tmpnam(b,e){ strcpy(b, "/tmp/lua_XXXXXX"); e = mkstemp(b); if (e != -1) close (e); e = (e == -1); } { e = (tmpnam(b) == NULL((void*)0)); } | |||
121 | ||||
122 | #endif /* } */ | |||
123 | ||||
124 | #endif /* } */ | |||
125 | /* }================================================================== */ | |||
126 | ||||
127 | ||||
128 | ||||
129 | ||||
130 | static int os_execute (lua_State *L) { | |||
131 | const char *cmd = luaL_optstring(L, 1, NULL)(luaL_optlstring(L, (1), (((void*)0)), ((void*)0))); | |||
132 | int stat = system(cmd); | |||
133 | if (cmd != NULL((void*)0)) | |||
134 | return luaL_execresult(L, stat); | |||
135 | else { | |||
136 | lua_pushboolean(L, stat); /* true if there is a shell */ | |||
137 | return 1; | |||
138 | } | |||
139 | } | |||
140 | ||||
141 | ||||
142 | static int os_remove (lua_State *L) { | |||
143 | const char *filename = luaL_checkstring(L, 1)(luaL_checklstring(L, (1), ((void*)0))); | |||
144 | return luaL_fileresult(L, remove(filename) == 0, filename); | |||
145 | } | |||
146 | ||||
147 | ||||
148 | static int os_rename (lua_State *L) { | |||
149 | const char *fromname = luaL_checkstring(L, 1)(luaL_checklstring(L, (1), ((void*)0))); | |||
150 | const char *toname = luaL_checkstring(L, 2)(luaL_checklstring(L, (2), ((void*)0))); | |||
151 | return luaL_fileresult(L, rename(fromname, toname) == 0, NULL((void*)0)); | |||
152 | } | |||
153 | ||||
154 | ||||
155 | static int os_tmpname (lua_State *L) { | |||
156 | char buff[LUA_TMPNAMBUFSIZE32]; | |||
157 | int err; | |||
158 | lua_tmpnam(buff, err){ strcpy(buff, "/tmp/lua_XXXXXX"); err = mkstemp(buff); if (err != -1) close(err); err = (err == -1); }; | |||
159 | if (err) | |||
160 | return luaL_error(L, "unable to generate a unique filename"); | |||
161 | lua_pushstring(L, buff); | |||
162 | return 1; | |||
163 | } | |||
164 | ||||
165 | ||||
166 | static int os_getenv (lua_State *L) { | |||
167 | lua_pushstring(L, getenv(luaL_checkstring(L, 1)(luaL_checklstring(L, (1), ((void*)0))))); /* if NULL push nil */ | |||
168 | return 1; | |||
169 | } | |||
170 | ||||
171 | ||||
172 | static int os_clock (lua_State *L) { | |||
173 | lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC((clock_t) 1000000)); | |||
174 | return 1; | |||
175 | } | |||
176 | ||||
177 | ||||
178 | /* | |||
179 | ** {====================================================== | |||
180 | ** Time/Date operations | |||
181 | ** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, | |||
182 | ** wday=%w+1, yday=%j, isdst=? } | |||
183 | ** ======================================================= | |||
184 | */ | |||
185 | ||||
186 | static void setfield (lua_State *L, const char *key, int value) { | |||
187 | lua_pushinteger(L, value); | |||
188 | lua_setfield(L, -2, key); | |||
189 | } | |||
190 | ||||
191 | static void setboolfield (lua_State *L, const char *key, int value) { | |||
192 | if (value < 0) /* undefined? */ | |||
193 | return; /* does not set field */ | |||
194 | lua_pushboolean(L, value); | |||
195 | lua_setfield(L, -2, key); | |||
196 | } | |||
197 | ||||
198 | static int getboolfield (lua_State *L, const char *key) { | |||
199 | int res; | |||
200 | res = (lua_getfield(L, -1, key) == LUA_TNIL0) ? -1 : lua_toboolean(L, -1); | |||
201 | lua_pop(L, 1)lua_settop(L, -(1)-1); | |||
202 | return res; | |||
203 | } | |||
204 | ||||
205 | ||||
206 | /* maximum value for date fields (to avoid arithmetic overflows with 'int') */ | |||
207 | #if !defined(L_MAXDATEFIELD(2147483647 / 2)) | |||
208 | #define L_MAXDATEFIELD(2147483647 / 2) (INT_MAX2147483647 / 2) | |||
209 | #endif | |||
210 | ||||
211 | static int getfield (lua_State *L, const char *key, int d, int delta) { | |||
212 | int isnum; | |||
213 | int t = lua_getfield(L, -1, key); | |||
214 | lua_Integer res = lua_tointegerx(L, -1, &isnum); | |||
215 | if (!isnum) { /* field is not a number? */ | |||
216 | if (t != LUA_TNIL0) /* some other value? */ | |||
217 | return luaL_error(L, "field '%s' not an integer", key); | |||
218 | else if (d < 0) /* absent field; no default? */ | |||
219 | return luaL_error(L, "field '%s' missing in date table", key); | |||
220 | res = d; | |||
221 | } | |||
222 | else { | |||
223 | if (!(-L_MAXDATEFIELD(2147483647 / 2) <= res && res <= L_MAXDATEFIELD(2147483647 / 2))) | |||
224 | return luaL_error(L, "field '%s' out-of-bounds", key); | |||
225 | res -= delta; | |||
226 | } | |||
227 | lua_pop(L, 1)lua_settop(L, -(1)-1); | |||
228 | return (int)res; | |||
229 | } | |||
230 | ||||
231 | ||||
232 | static const char *checkoption (lua_State *L, const char *conv, char *buff) { | |||
233 | static const char *const options[] = LUA_STRFTIMEOPTIONS{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", "E", "cCxXyY", "O", "deHImMSuUVwWy" }; | |||
234 | unsigned int i; | |||
235 | for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { | |||
236 | if (*conv != '\0' && strchr(options[i], *conv)(__extension__ (__builtin_constant_p (*conv) && !__builtin_constant_p (options[i]) && (*conv) == '\0' ? (char *) __rawmemchr (options[i], *conv) : __builtin_strchr (options[i], *conv))) != NULL((void*)0)) { | |||
237 | buff[1] = *conv; | |||
238 | if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ | |||
239 | buff[2] = '\0'; /* end buffer */ | |||
240 | return conv + 1; | |||
241 | } | |||
242 | else if (*(conv + 1) != '\0' && | |||
243 | strchr(options[i + 1], *(conv + 1))(__extension__ (__builtin_constant_p (*(conv + 1)) && !__builtin_constant_p (options[i + 1]) && (*(conv + 1 )) == '\0' ? (char *) __rawmemchr (options[i + 1], *(conv + 1 )) : __builtin_strchr (options[i + 1], *(conv + 1)))) != NULL((void*)0)) { | |||
244 | buff[2] = *(conv + 1); /* valid two-char conversion specifier */ | |||
245 | buff[3] = '\0'; /* end buffer */ | |||
246 | return conv + 2; | |||
247 | } | |||
248 | } | |||
249 | } | |||
250 | luaL_argerror(L, 1, | |||
251 | lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); | |||
252 | return conv; /* to avoid warnings */ | |||
253 | } | |||
254 | ||||
255 | ||||
256 | /* maximum size for an individual 'strftime' item */ | |||
257 | #define SIZETIMEFMT250 250 | |||
258 | ||||
259 | ||||
260 | static int os_date (lua_State *L) { | |||
261 | const char *s = luaL_optstring(L, 1, "%c")(luaL_optlstring(L, (1), ("%c"), ((void*)0))); | |||
262 | time_t t = luaL_opt(L, l_checktime, 2, time(NULL))((lua_type(L, ((2))) <= 0) ? (time(((void*)0))) : l_checktime (L,(2))); | |||
263 | struct tm tmr, *stm; | |||
264 | if (*s == '!') { /* UTC? */ | |||
| ||||
265 | stm = l_gmtime(&t, &tmr)gmtime_r(&t,&tmr); | |||
266 | s++; /* skip '!' */ | |||
267 | } | |||
268 | else | |||
269 | stm = l_localtime(&t, &tmr)localtime_r(&t,&tmr); | |||
270 | if (stm == NULL((void*)0)) /* invalid date? */ | |||
271 | luaL_error(L, "time result cannot be represented in this installation"); | |||
272 | if (strcmp(s, "*t")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (s) && __builtin_constant_p ("*t") && (__s1_len = __builtin_strlen (s), __s2_len = __builtin_strlen ("*t"), ( !((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(("*t") + 1) - (size_t)(const void *)("*t") == 1) || __s2_len >= 4)) ? __builtin_strcmp (s, "*t") : (__builtin_constant_p (s) && ((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) && (__s1_len = __builtin_strlen (s) , __s1_len < 4) ? (__builtin_constant_p ("*t") && ( (size_t)(const void *)(("*t") + 1) - (size_t)(const void *)("*t" ) == 1) ? __builtin_strcmp (s, "*t") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("*t"); int __result = (((const unsigned char *) (const char *) (s))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( s))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (s) )[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (s))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("*t" ) && ((size_t)(const void *)(("*t") + 1) - (size_t)(const void *)("*t") == 1) && (__s2_len = __builtin_strlen ( "*t"), __s2_len < 4) ? (__builtin_constant_p (s) && ((size_t)(const void *)((s) + 1) - (size_t)(const void *)(s) == 1) ? __builtin_strcmp (s, "*t") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (s); int __result = (((const unsigned char *) (const char *) ("*t"))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "*t"))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ( "*t"))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("*t" ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s, "*t" )))); }) == 0) { | |||
273 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | |||
274 | setfield(L, "sec", stm->tm_sec); | |||
| ||||
275 | setfield(L, "min", stm->tm_min); | |||
276 | setfield(L, "hour", stm->tm_hour); | |||
277 | setfield(L, "day", stm->tm_mday); | |||
278 | setfield(L, "month", stm->tm_mon+1); | |||
279 | setfield(L, "year", stm->tm_year+1900); | |||
280 | setfield(L, "wday", stm->tm_wday+1); | |||
281 | setfield(L, "yday", stm->tm_yday+1); | |||
282 | setboolfield(L, "isdst", stm->tm_isdst); | |||
283 | } | |||
284 | else { | |||
285 | char cc[4]; | |||
286 | luaL_Buffer b; | |||
287 | cc[0] = '%'; | |||
288 | luaL_buffinit(L, &b); | |||
289 | while (*s) { | |||
290 | if (*s != '%') /* not a conversion specifier? */ | |||
291 | luaL_addchar(&b, *s++)((void)((&b)->n < (&b)->size || luaL_prepbuffsize ((&b), 1)), ((&b)->b[(&b)->n++] = (*s++))); | |||
292 | else { | |||
293 | size_t reslen; | |||
294 | char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT250); | |||
295 | s = checkoption(L, s + 1, cc); | |||
296 | reslen = strftime(buff, SIZETIMEFMT250, cc, stm); | |||
297 | luaL_addsize(&b, reslen)((&b)->n += (reslen)); | |||
298 | } | |||
299 | } | |||
300 | luaL_pushresult(&b); | |||
301 | } | |||
302 | return 1; | |||
303 | } | |||
304 | ||||
305 | ||||
306 | static int os_time (lua_State *L) { | |||
307 | time_t t; | |||
308 | if (lua_isnoneornil(L, 1)(lua_type(L, (1)) <= 0)) /* called without args? */ | |||
309 | t = time(NULL((void*)0)); /* get current time */ | |||
310 | else { | |||
311 | struct tm ts; | |||
312 | luaL_checktype(L, 1, LUA_TTABLE5); | |||
313 | lua_settop(L, 1); /* make sure table is at the top */ | |||
314 | ts.tm_sec = getfield(L, "sec", 0, 0); | |||
315 | ts.tm_min = getfield(L, "min", 0, 0); | |||
316 | ts.tm_hour = getfield(L, "hour", 12, 0); | |||
317 | ts.tm_mday = getfield(L, "day", -1, 0); | |||
318 | ts.tm_mon = getfield(L, "month", -1, 1); | |||
319 | ts.tm_year = getfield(L, "year", -1, 1900); | |||
320 | ts.tm_isdst = getboolfield(L, "isdst"); | |||
321 | t = mktime(&ts); | |||
322 | } | |||
323 | if (t != (time_t)(l_timetlua_Integer)t || t == (time_t)(-1)) | |||
324 | luaL_error(L, "time result cannot be represented in this installation"); | |||
325 | l_pushtime(L, t)lua_pushinteger(L,(lua_Integer)(t)); | |||
326 | return 1; | |||
327 | } | |||
328 | ||||
329 | ||||
330 | static int os_difftime (lua_State *L) { | |||
331 | time_t t1 = l_checktime(L, 1); | |||
332 | time_t t2 = l_checktime(L, 2); | |||
333 | lua_pushnumber(L, (lua_Number)difftime(t1, t2)); | |||
334 | return 1; | |||
335 | } | |||
336 | ||||
337 | /* }====================================================== */ | |||
338 | ||||
339 | ||||
340 | static int os_setlocale (lua_State *L) { | |||
341 | static const int cat[] = {LC_ALL6, LC_COLLATE3, LC_CTYPE0, LC_MONETARY4, | |||
342 | LC_NUMERIC1, LC_TIME2}; | |||
343 | static const char *const catnames[] = {"all", "collate", "ctype", "monetary", | |||
344 | "numeric", "time", NULL((void*)0)}; | |||
345 | const char *l = luaL_optstring(L, 1, NULL)(luaL_optlstring(L, (1), (((void*)0)), ((void*)0))); | |||
346 | int op = luaL_checkoption(L, 2, "all", catnames); | |||
347 | lua_pushstring(L, setlocale(cat[op], l)); | |||
348 | return 1; | |||
349 | } | |||
350 | ||||
351 | ||||
352 | static int os_exit (lua_State *L) { | |||
353 | int status; | |||
354 | if (lua_isboolean(L, 1)(lua_type(L, (1)) == 1)) | |||
355 | status = (lua_toboolean(L, 1) ? EXIT_SUCCESS0 : EXIT_FAILURE1); | |||
356 | else | |||
357 | status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS0); | |||
358 | if (lua_toboolean(L, 2)) | |||
359 | lua_close(L); | |||
360 | if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ | |||
361 | return 0; | |||
362 | } | |||
363 | ||||
364 | ||||
365 | static const luaL_Reg syslib[] = { | |||
366 | {"clock", os_clock}, | |||
367 | {"date", os_date}, | |||
368 | {"difftime", os_difftime}, | |||
369 | {"execute", os_execute}, | |||
370 | {"exit", os_exit}, | |||
371 | {"getenv", os_getenv}, | |||
372 | {"remove", os_remove}, | |||
373 | {"rename", os_rename}, | |||
374 | {"setlocale", os_setlocale}, | |||
375 | {"time", os_time}, | |||
376 | {"tmpname", os_tmpname}, | |||
377 | {NULL((void*)0), NULL((void*)0)} | |||
378 | }; | |||
379 | ||||
380 | /* }====================================================== */ | |||
381 | ||||
382 | ||||
383 | ||||
384 | LUAMOD_APIextern int luaopen_os (lua_State *L) { | |||
385 | luaL_newlib(L, syslib)(luaL_checkversion_(L, 503, (sizeof(lua_Integer)*16 + sizeof( lua_Number))), lua_createtable(L, 0, sizeof(syslib)/sizeof((syslib )[0]) - 1), luaL_setfuncs(L,syslib,0)); | |||
386 | return 1; | |||
387 | } | |||
388 |