Comparison

util-src/pposix.c @ 6621:352fa2cae1c9

Merge 0.10->trunk
author Matthew Wild <mwild1@gmail.com>
date Fri, 03 Apr 2015 19:34:47 +0100
parent 6620:50eaefeec013
child 6642:113d321976b6
comparison
equal deleted inserted replaced
6614:c78f8f8f4434 6621:352fa2cae1c9
43 #if defined(__linux__) && defined(_GNU_SOURCE) 43 #if defined(__linux__) && defined(_GNU_SOURCE)
44 #include <linux/falloc.h> 44 #include <linux/falloc.h>
45 #endif 45 #endif
46 46
47 #if (defined(_SVID_SOURCE) && !defined(WITHOUT_MALLINFO)) 47 #if (defined(_SVID_SOURCE) && !defined(WITHOUT_MALLINFO))
48 #include <malloc.h> 48 #include <malloc.h>
49 #define WITH_MALLINFO 49 #define WITH_MALLINFO
50 #endif 50 #endif
51 51
52 /* Daemonization support */ 52 /* Daemonization support */
53 53
54 static int lc_daemonize(lua_State *L) 54 static int lc_daemonize(lua_State* L) {
55 {
56 55
57 pid_t pid; 56 pid_t pid;
58 57
59 if ( getppid() == 1 ) 58 if(getppid() == 1) {
60 {
61 lua_pushboolean(L, 0); 59 lua_pushboolean(L, 0);
62 lua_pushstring(L, "already-daemonized"); 60 lua_pushstring(L, "already-daemonized");
63 return 2; 61 return 2;
64 } 62 }
65 63
66 /* Attempt initial fork */ 64 /* Attempt initial fork */
67 if((pid = fork()) < 0) 65 if((pid = fork()) < 0) {
68 {
69 /* Forking failed */ 66 /* Forking failed */
70 lua_pushboolean(L, 0); 67 lua_pushboolean(L, 0);
71 lua_pushstring(L, "fork-failed"); 68 lua_pushstring(L, "fork-failed");
72 return 2; 69 return 2;
73 } 70 } else if(pid != 0) {
74 else if(pid != 0)
75 {
76 /* We are the parent process */ 71 /* We are the parent process */
77 lua_pushboolean(L, 1); 72 lua_pushboolean(L, 1);
78 lua_pushnumber(L, pid); 73 lua_pushnumber(L, pid);
79 return 2; 74 return 2;
80 } 75 }
81 76
82 /* and we are the child process */ 77 /* and we are the child process */
83 if(setsid() == -1) 78 if(setsid() == -1) {
84 {
85 /* We failed to become session leader */ 79 /* We failed to become session leader */
86 /* (we probably already were) */ 80 /* (we probably already were) */
87 lua_pushboolean(L, 0); 81 lua_pushboolean(L, 0);
88 lua_pushstring(L, "setsid-failed"); 82 lua_pushstring(L, "setsid-failed");
89 return 2; 83 return 2;
97 open("/dev/null", O_RDONLY); 91 open("/dev/null", O_RDONLY);
98 open("/dev/null", O_WRONLY); 92 open("/dev/null", O_WRONLY);
99 open("/dev/null", O_WRONLY); 93 open("/dev/null", O_WRONLY);
100 94
101 /* Final fork, use it wisely */ 95 /* Final fork, use it wisely */
102 if(fork()) 96 if(fork()) {
103 exit(0); 97 exit(0);
98 }
104 99
105 /* Show's over, let's continue */ 100 /* Show's over, let's continue */
106 lua_pushboolean(L, 1); 101 lua_pushboolean(L, 1);
107 lua_pushnil(L); 102 lua_pushnil(L);
108 return 2; 103 return 2;
109 } 104 }
110 105
111 /* Syslog support */ 106 /* Syslog support */
112 107
113 const char * const facility_strings[] = { 108 const char* const facility_strings[] = {
114 "auth", 109 "auth",
115 #if !(defined(sun) || defined(__sun)) 110 #if !(defined(sun) || defined(__sun))
116 "authpriv", 111 "authpriv",
117 #endif 112 #endif
118 "cron", 113 "cron",
119 "daemon", 114 "daemon",
120 #if !(defined(sun) || defined(__sun)) 115 #if !(defined(sun) || defined(__sun))
121 "ftp", 116 "ftp",
122 #endif 117 #endif
123 "kern", 118 "kern",
124 "local0", 119 "local0",
125 "local1", 120 "local1",
126 "local2", 121 "local2",
127 "local3", 122 "local3",
128 "local4", 123 "local4",
129 "local5", 124 "local5",
130 "local6", 125 "local6",
131 "local7", 126 "local7",
132 "lpr", 127 "lpr",
133 "mail", 128 "mail",
134 "syslog", 129 "syslog",
135 "user", 130 "user",
136 "uucp", 131 "uucp",
137 NULL 132 NULL
138 }; 133 };
139 int facility_constants[] = { 134 int facility_constants[] = {
140 LOG_AUTH, 135 LOG_AUTH,
141 #if !(defined(sun) || defined(__sun)) 136 #if !(defined(sun) || defined(__sun))
142 LOG_AUTHPRIV, 137 LOG_AUTHPRIV,
143 #endif 138 #endif
144 LOG_CRON, 139 LOG_CRON,
145 LOG_DAEMON, 140 LOG_DAEMON,
146 #if !(defined(sun) || defined(__sun)) 141 #if !(defined(sun) || defined(__sun))
147 LOG_FTP, 142 LOG_FTP,
148 #endif 143 #endif
149 LOG_KERN, 144 LOG_KERN,
150 LOG_LOCAL0, 145 LOG_LOCAL0,
151 LOG_LOCAL1, 146 LOG_LOCAL1,
152 LOG_LOCAL2, 147 LOG_LOCAL2,
153 LOG_LOCAL3, 148 LOG_LOCAL3,
154 LOG_LOCAL4, 149 LOG_LOCAL4,
155 LOG_LOCAL5, 150 LOG_LOCAL5,
156 LOG_LOCAL6, 151 LOG_LOCAL6,
157 LOG_LOCAL7, 152 LOG_LOCAL7,
158 LOG_LPR, 153 LOG_LPR,
159 LOG_MAIL, 154 LOG_MAIL,
160 LOG_NEWS, 155 LOG_NEWS,
161 LOG_SYSLOG, 156 LOG_SYSLOG,
162 LOG_USER, 157 LOG_USER,
163 LOG_UUCP, 158 LOG_UUCP,
164 -1 159 -1
165 }; 160 };
166 161
167 /* " 162 /* "
168 The parameter ident in the call of openlog() is probably stored as-is. 163 The parameter ident in the call of openlog() is probably stored as-is.
169 Thus, if the string it points to is changed, syslog() may start 164 Thus, if the string it points to is changed, syslog() may start
170 prepending the changed string, and if the string it points to ceases to 165 prepending the changed string, and if the string it points to ceases to
172 constant. 167 constant.
173 " -- syslog manpage 168 " -- syslog manpage
174 */ 169 */
175 char* syslog_ident = NULL; 170 char* syslog_ident = NULL;
176 171
177 int lc_syslog_open(lua_State* L) 172 int lc_syslog_open(lua_State* L) {
178 {
179 int facility = luaL_checkoption(L, 2, "daemon", facility_strings); 173 int facility = luaL_checkoption(L, 2, "daemon", facility_strings);
180 facility = facility_constants[facility]; 174 facility = facility_constants[facility];
181 175
182 luaL_checkstring(L, 1); 176 luaL_checkstring(L, 1);
183 177
184 if(syslog_ident) 178 if(syslog_ident) {
185 free(syslog_ident); 179 free(syslog_ident);
180 }
186 181
187 syslog_ident = strdup(lua_tostring(L, 1)); 182 syslog_ident = strdup(lua_tostring(L, 1));
188 183
189 openlog(syslog_ident, LOG_PID, facility); 184 openlog(syslog_ident, LOG_PID, facility);
190 return 0; 185 return 0;
191 } 186 }
192 187
193 const char * const level_strings[] = { 188 const char* const level_strings[] = {
194 "debug", 189 "debug",
195 "info", 190 "info",
196 "notice", 191 "notice",
197 "warn", 192 "warn",
198 "error", 193 "error",
199 NULL 194 NULL
200 }; 195 };
201 int level_constants[] = { 196 int level_constants[] = {
202 LOG_DEBUG, 197 LOG_DEBUG,
203 LOG_INFO, 198 LOG_INFO,
204 LOG_NOTICE, 199 LOG_NOTICE,
205 LOG_WARNING, 200 LOG_WARNING,
206 LOG_CRIT, 201 LOG_CRIT,
207 -1 202 -1
208 }; 203 };
209 int lc_syslog_log(lua_State* L) 204 int lc_syslog_log(lua_State* L) {
210 {
211 int level = level_constants[luaL_checkoption(L, 1, "notice", level_strings)]; 205 int level = level_constants[luaL_checkoption(L, 1, "notice", level_strings)];
212 206
213 if(lua_gettop(L) == 3) 207 if(lua_gettop(L) == 3) {
214 syslog(level, "%s: %s", luaL_checkstring(L, 2), luaL_checkstring(L, 3)); 208 syslog(level, "%s: %s", luaL_checkstring(L, 2), luaL_checkstring(L, 3));
215 else 209 } else {
216 syslog(level, "%s", lua_tostring(L, 2)); 210 syslog(level, "%s", lua_tostring(L, 2));
211 }
217 212
218 return 0; 213 return 0;
219 } 214 }
220 215
221 int lc_syslog_close(lua_State* L) 216 int lc_syslog_close(lua_State* L) {
222 {
223 closelog(); 217 closelog();
224 if(syslog_ident) 218
225 { 219 if(syslog_ident) {
226 free(syslog_ident); 220 free(syslog_ident);
227 syslog_ident = NULL; 221 syslog_ident = NULL;
228 } 222 }
223
229 return 0; 224 return 0;
230 } 225 }
231 226
232 int lc_syslog_setmask(lua_State* L) 227 int lc_syslog_setmask(lua_State* L) {
233 {
234 int level_idx = luaL_checkoption(L, 1, "notice", level_strings); 228 int level_idx = luaL_checkoption(L, 1, "notice", level_strings);
235 int mask = 0; 229 int mask = 0;
236 do 230
237 { 231 do {
238 mask |= LOG_MASK(level_constants[level_idx]); 232 mask |= LOG_MASK(level_constants[level_idx]);
239 } while (++level_idx<=4); 233 } while(++level_idx <= 4);
240 234
241 setlogmask(mask); 235 setlogmask(mask);
242 return 0; 236 return 0;
243 } 237 }
244 238
245 /* getpid */ 239 /* getpid */
246 240
247 int lc_getpid(lua_State* L) 241 int lc_getpid(lua_State* L) {
248 {
249 lua_pushinteger(L, getpid()); 242 lua_pushinteger(L, getpid());
250 return 1; 243 return 1;
251 } 244 }
252 245
253 /* UID/GID functions */ 246 /* UID/GID functions */
254 247
255 int lc_getuid(lua_State* L) 248 int lc_getuid(lua_State* L) {
256 {
257 lua_pushinteger(L, getuid()); 249 lua_pushinteger(L, getuid());
258 return 1; 250 return 1;
259 } 251 }
260 252
261 int lc_getgid(lua_State* L) 253 int lc_getgid(lua_State* L) {
262 {
263 lua_pushinteger(L, getgid()); 254 lua_pushinteger(L, getgid());
264 return 1; 255 return 1;
265 } 256 }
266 257
267 int lc_setuid(lua_State* L) 258 int lc_setuid(lua_State* L) {
268 {
269 int uid = -1; 259 int uid = -1;
270 if(lua_gettop(L) < 1) 260
261 if(lua_gettop(L) < 1) {
271 return 0; 262 return 0;
272 if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) 263 }
273 { 264
265 if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) {
274 /* Passed UID is actually a string, so look up the UID */ 266 /* Passed UID is actually a string, so look up the UID */
275 struct passwd *p; 267 struct passwd* p;
276 p = getpwnam(lua_tostring(L, 1)); 268 p = getpwnam(lua_tostring(L, 1));
277 if(!p) 269
278 { 270 if(!p) {
279 lua_pushboolean(L, 0); 271 lua_pushboolean(L, 0);
280 lua_pushstring(L, "no-such-user"); 272 lua_pushstring(L, "no-such-user");
281 return 2; 273 return 2;
282 } 274 }
275
283 uid = p->pw_uid; 276 uid = p->pw_uid;
284 } 277 } else {
285 else
286 {
287 uid = lua_tonumber(L, 1); 278 uid = lua_tonumber(L, 1);
288 } 279 }
289 280
290 if(uid>-1) 281 if(uid > -1) {
291 {
292 /* Ok, attempt setuid */ 282 /* Ok, attempt setuid */
293 errno = 0; 283 errno = 0;
294 if(setuid(uid)) 284
295 { 285 if(setuid(uid)) {
296 /* Fail */ 286 /* Fail */
297 lua_pushboolean(L, 0); 287 lua_pushboolean(L, 0);
298 switch(errno) 288
299 { 289 switch(errno) {
300 case EINVAL: 290 case EINVAL:
301 lua_pushstring(L, "invalid-uid"); 291 lua_pushstring(L, "invalid-uid");
302 break; 292 break;
303 case EPERM: 293 case EPERM:
304 lua_pushstring(L, "permission-denied"); 294 lua_pushstring(L, "permission-denied");
305 break; 295 break;
306 default: 296 default:
307 lua_pushstring(L, "unknown-error"); 297 lua_pushstring(L, "unknown-error");
308 } 298 }
299
309 return 2; 300 return 2;
310 } 301 } else {
311 else
312 {
313 /* Success! */ 302 /* Success! */
314 lua_pushboolean(L, 1); 303 lua_pushboolean(L, 1);
315 return 1; 304 return 1;
316 } 305 }
317 } 306 }
320 lua_pushboolean(L, 0); 309 lua_pushboolean(L, 0);
321 lua_pushstring(L, "invalid-uid"); 310 lua_pushstring(L, "invalid-uid");
322 return 2; 311 return 2;
323 } 312 }
324 313
325 int lc_setgid(lua_State* L) 314 int lc_setgid(lua_State* L) {
326 {
327 int gid = -1; 315 int gid = -1;
328 if(lua_gettop(L) < 1) 316
317 if(lua_gettop(L) < 1) {
329 return 0; 318 return 0;
330 if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) 319 }
331 { 320
321 if(!lua_isnumber(L, 1) && lua_tostring(L, 1)) {
332 /* Passed GID is actually a string, so look up the GID */ 322 /* Passed GID is actually a string, so look up the GID */
333 struct group *g; 323 struct group* g;
334 g = getgrnam(lua_tostring(L, 1)); 324 g = getgrnam(lua_tostring(L, 1));
335 if(!g) 325
336 { 326 if(!g) {
337 lua_pushboolean(L, 0); 327 lua_pushboolean(L, 0);
338 lua_pushstring(L, "no-such-group"); 328 lua_pushstring(L, "no-such-group");
339 return 2; 329 return 2;
340 } 330 }
331
341 gid = g->gr_gid; 332 gid = g->gr_gid;
342 } 333 } else {
343 else
344 {
345 gid = lua_tonumber(L, 1); 334 gid = lua_tonumber(L, 1);
346 } 335 }
347 336
348 if(gid>-1) 337 if(gid > -1) {
349 {
350 /* Ok, attempt setgid */ 338 /* Ok, attempt setgid */
351 errno = 0; 339 errno = 0;
352 if(setgid(gid)) 340
353 { 341 if(setgid(gid)) {
354 /* Fail */ 342 /* Fail */
355 lua_pushboolean(L, 0); 343 lua_pushboolean(L, 0);
356 switch(errno) 344
357 { 345 switch(errno) {
358 case EINVAL: 346 case EINVAL:
359 lua_pushstring(L, "invalid-gid"); 347 lua_pushstring(L, "invalid-gid");
360 break; 348 break;
361 case EPERM: 349 case EPERM:
362 lua_pushstring(L, "permission-denied"); 350 lua_pushstring(L, "permission-denied");
363 break; 351 break;
364 default: 352 default:
365 lua_pushstring(L, "unknown-error"); 353 lua_pushstring(L, "unknown-error");
366 } 354 }
355
367 return 2; 356 return 2;
368 } 357 } else {
369 else
370 {
371 /* Success! */ 358 /* Success! */
372 lua_pushboolean(L, 1); 359 lua_pushboolean(L, 1);
373 return 1; 360 return 1;
374 } 361 }
375 } 362 }
378 lua_pushboolean(L, 0); 365 lua_pushboolean(L, 0);
379 lua_pushstring(L, "invalid-gid"); 366 lua_pushstring(L, "invalid-gid");
380 return 2; 367 return 2;
381 } 368 }
382 369
383 int lc_initgroups(lua_State* L) 370 int lc_initgroups(lua_State* L) {
384 {
385 int ret; 371 int ret;
386 gid_t gid; 372 gid_t gid;
387 struct passwd *p; 373 struct passwd* p;
388 374
389 if(!lua_isstring(L, 1)) 375 if(!lua_isstring(L, 1)) {
390 {
391 lua_pushnil(L); 376 lua_pushnil(L);
392 lua_pushstring(L, "invalid-username"); 377 lua_pushstring(L, "invalid-username");
393 return 2; 378 return 2;
394 } 379 }
380
395 p = getpwnam(lua_tostring(L, 1)); 381 p = getpwnam(lua_tostring(L, 1));
396 if(!p) 382
397 { 383 if(!p) {
398 lua_pushnil(L); 384 lua_pushnil(L);
399 lua_pushstring(L, "no-such-user"); 385 lua_pushstring(L, "no-such-user");
400 return 2; 386 return 2;
401 } 387 }
402 if(lua_gettop(L) < 2) 388
389 if(lua_gettop(L) < 2) {
403 lua_pushnil(L); 390 lua_pushnil(L);
404 switch(lua_type(L, 2)) 391 }
405 { 392
406 case LUA_TNIL: 393 switch(lua_type(L, 2)) {
407 gid = p->pw_gid; 394 case LUA_TNIL:
408 break; 395 gid = p->pw_gid;
409 case LUA_TNUMBER:
410 gid = lua_tointeger(L, 2);
411 break;
412 default:
413 lua_pushnil(L);
414 lua_pushstring(L, "invalid-gid");
415 return 2;
416 }
417 ret = initgroups(lua_tostring(L, 1), gid);
418 if(ret)
419 {
420 switch(errno)
421 {
422 case ENOMEM:
423 lua_pushnil(L);
424 lua_pushstring(L, "no-memory");
425 break; 396 break;
426 case EPERM: 397 case LUA_TNUMBER:
427 lua_pushnil(L); 398 gid = lua_tointeger(L, 2);
428 lua_pushstring(L, "permission-denied");
429 break; 399 break;
430 default: 400 default:
431 lua_pushnil(L); 401 lua_pushnil(L);
432 lua_pushstring(L, "unknown-error"); 402 lua_pushstring(L, "invalid-gid");
403 return 2;
404 }
405
406 ret = initgroups(lua_tostring(L, 1), gid);
407
408 if(ret) {
409 switch(errno) {
410 case ENOMEM:
411 lua_pushnil(L);
412 lua_pushstring(L, "no-memory");
413 break;
414 case EPERM:
415 lua_pushnil(L);
416 lua_pushstring(L, "permission-denied");
417 break;
418 default:
419 lua_pushnil(L);
420 lua_pushstring(L, "unknown-error");
433 } 421 }
434 } 422 } else {
435 else
436 {
437 lua_pushboolean(L, 1); 423 lua_pushboolean(L, 1);
438 lua_pushnil(L); 424 lua_pushnil(L);
439 } 425 }
426
440 return 2; 427 return 2;
441 } 428 }
442 429
443 int lc_umask(lua_State* L) 430 int lc_umask(lua_State* L) {
444 {
445 char old_mode_string[7]; 431 char old_mode_string[7];
446 mode_t old_mode = umask(strtoul(luaL_checkstring(L, 1), NULL, 8)); 432 mode_t old_mode = umask(strtoul(luaL_checkstring(L, 1), NULL, 8));
447 433
448 snprintf(old_mode_string, sizeof(old_mode_string), "%03o", old_mode); 434 snprintf(old_mode_string, sizeof(old_mode_string), "%03o", old_mode);
449 old_mode_string[sizeof(old_mode_string)-1] = 0; 435 old_mode_string[sizeof(old_mode_string) - 1] = 0;
450 lua_pushstring(L, old_mode_string); 436 lua_pushstring(L, old_mode_string);
451 437
452 return 1; 438 return 1;
453 } 439 }
454 440
455 int lc_mkdir(lua_State* L) 441 int lc_mkdir(lua_State* L) {
456 {
457 int ret = mkdir(luaL_checkstring(L, 1), S_IRUSR | S_IWUSR | S_IXUSR 442 int ret = mkdir(luaL_checkstring(L, 1), S_IRUSR | S_IWUSR | S_IXUSR
458 | S_IRGRP | S_IWGRP | S_IXGRP 443 | S_IRGRP | S_IWGRP | S_IXGRP
459 | S_IROTH | S_IXOTH); /* mode 775 */ 444 | S_IROTH | S_IXOTH); /* mode 775 */
460 445
461 lua_pushboolean(L, ret==0); 446 lua_pushboolean(L, ret == 0);
462 if(ret) 447
463 { 448 if(ret) {
464 lua_pushstring(L, strerror(errno)); 449 lua_pushstring(L, strerror(errno));
465 return 2; 450 return 2;
466 } 451 }
452
467 return 1; 453 return 1;
468 } 454 }
469 455
470 /* Like POSIX's setrlimit()/getrlimit() API functions. 456 /* Like POSIX's setrlimit()/getrlimit() API functions.
471 * 457 *
475 * Any negative limit will be replace with the current limit by an additional call of getrlimit(). 461 * Any negative limit will be replace with the current limit by an additional call of getrlimit().
476 * 462 *
477 * Example usage: 463 * Example usage:
478 * pposix.setrlimit("NOFILE", 1000, 2000) 464 * pposix.setrlimit("NOFILE", 1000, 2000)
479 */ 465 */
480 int string2resource(const char *s) { 466 int string2resource(const char* s) {
481 if (!strcmp(s, "CORE")) return RLIMIT_CORE; 467 if(!strcmp(s, "CORE")) {
482 if (!strcmp(s, "CPU")) return RLIMIT_CPU; 468 return RLIMIT_CORE;
483 if (!strcmp(s, "DATA")) return RLIMIT_DATA; 469 }
484 if (!strcmp(s, "FSIZE")) return RLIMIT_FSIZE; 470
485 if (!strcmp(s, "NOFILE")) return RLIMIT_NOFILE; 471 if(!strcmp(s, "CPU")) {
486 if (!strcmp(s, "STACK")) return RLIMIT_STACK; 472 return RLIMIT_CPU;
473 }
474
475 if(!strcmp(s, "DATA")) {
476 return RLIMIT_DATA;
477 }
478
479 if(!strcmp(s, "FSIZE")) {
480 return RLIMIT_FSIZE;
481 }
482
483 if(!strcmp(s, "NOFILE")) {
484 return RLIMIT_NOFILE;
485 }
486
487 if(!strcmp(s, "STACK")) {
488 return RLIMIT_STACK;
489 }
490
487 #if !(defined(sun) || defined(__sun)) 491 #if !(defined(sun) || defined(__sun))
488 if (!strcmp(s, "MEMLOCK")) return RLIMIT_MEMLOCK; 492
489 if (!strcmp(s, "NPROC")) return RLIMIT_NPROC; 493 if(!strcmp(s, "MEMLOCK")) {
490 if (!strcmp(s, "RSS")) return RLIMIT_RSS; 494 return RLIMIT_MEMLOCK;
495 }
496
497 if(!strcmp(s, "NPROC")) {
498 return RLIMIT_NPROC;
499 }
500
501 if(!strcmp(s, "RSS")) {
502 return RLIMIT_RSS;
503 }
504
491 #endif 505 #endif
492 #ifdef RLIMIT_NICE 506 #ifdef RLIMIT_NICE
493 if (!strcmp(s, "NICE")) return RLIMIT_NICE; 507
508 if(!strcmp(s, "NICE")) {
509 return RLIMIT_NICE;
510 }
511
494 #endif 512 #endif
495 return -1; 513 return -1;
496 } 514 }
497 515
498 unsigned long int arg_to_rlimit(lua_State* L, int idx, rlim_t current) { 516 unsigned long int arg_to_rlimit(lua_State* L, int idx, rlim_t current) {
499 switch(lua_type(L, idx)) { 517 switch(lua_type(L, idx)) {
500 case LUA_TSTRING: 518 case LUA_TSTRING:
501 if(strcmp(lua_tostring(L, idx), "unlimited") == 0) 519
502 return RLIM_INFINITY; 520 if(strcmp(lua_tostring(L, idx), "unlimited") == 0) {
503 case LUA_TNUMBER: 521 return RLIM_INFINITY;
504 return lua_tointeger(L, idx); 522 }
505 case LUA_TNONE: 523
506 case LUA_TNIL: 524 case LUA_TNUMBER:
507 return current; 525 return lua_tointeger(L, idx);
508 default: 526 case LUA_TNONE:
509 return luaL_argerror(L, idx, "unexpected type"); 527 case LUA_TNIL:
510 } 528 return current;
511 } 529 default:
512 530 return luaL_argerror(L, idx, "unexpected type");
513 int lc_setrlimit(lua_State *L) { 531 }
532 }
533
534 int lc_setrlimit(lua_State* L) {
514 struct rlimit lim; 535 struct rlimit lim;
515 int arguments = lua_gettop(L); 536 int arguments = lua_gettop(L);
516 int rid = -1; 537 int rid = -1;
538
517 if(arguments < 1 || arguments > 3) { 539 if(arguments < 1 || arguments > 3) {
518 lua_pushboolean(L, 0); 540 lua_pushboolean(L, 0);
519 lua_pushstring(L, "incorrect-arguments"); 541 lua_pushstring(L, "incorrect-arguments");
520 return 2; 542 return 2;
521 } 543 }
522 544
523 rid = string2resource(luaL_checkstring(L, 1)); 545 rid = string2resource(luaL_checkstring(L, 1));
524 if (rid == -1) { 546
547 if(rid == -1) {
525 lua_pushboolean(L, 0); 548 lua_pushboolean(L, 0);
526 lua_pushstring(L, "invalid-resource"); 549 lua_pushstring(L, "invalid-resource");
527 return 2; 550 return 2;
528 } 551 }
529 552
530 /* Fetch current values to use as defaults */ 553 /* Fetch current values to use as defaults */
531 if (getrlimit(rid, &lim)) { 554 if(getrlimit(rid, &lim)) {
532 lua_pushboolean(L, 0); 555 lua_pushboolean(L, 0);
533 lua_pushstring(L, "getrlimit-failed"); 556 lua_pushstring(L, "getrlimit-failed");
534 return 2; 557 return 2;
535 } 558 }
536 559
537 lim.rlim_cur = arg_to_rlimit(L, 2, lim.rlim_cur); 560 lim.rlim_cur = arg_to_rlimit(L, 2, lim.rlim_cur);
538 lim.rlim_max = arg_to_rlimit(L, 3, lim.rlim_max); 561 lim.rlim_max = arg_to_rlimit(L, 3, lim.rlim_max);
539 562
540 if (setrlimit(rid, &lim)) { 563 if(setrlimit(rid, &lim)) {
541 lua_pushboolean(L, 0); 564 lua_pushboolean(L, 0);
542 lua_pushstring(L, "setrlimit-failed"); 565 lua_pushstring(L, "setrlimit-failed");
543 return 2; 566 return 2;
544 } 567 }
568
545 lua_pushboolean(L, 1); 569 lua_pushboolean(L, 1);
546 return 1; 570 return 1;
547 } 571 }
548 572
549 int lc_getrlimit(lua_State *L) { 573 int lc_getrlimit(lua_State* L) {
550 int arguments = lua_gettop(L); 574 int arguments = lua_gettop(L);
551 const char *resource = NULL; 575 const char* resource = NULL;
552 int rid = -1; 576 int rid = -1;
553 struct rlimit lim; 577 struct rlimit lim;
554 578
555 if (arguments != 1) { 579 if(arguments != 1) {
556 lua_pushboolean(L, 0); 580 lua_pushboolean(L, 0);
557 lua_pushstring(L, "invalid-arguments"); 581 lua_pushstring(L, "invalid-arguments");
558 return 2; 582 return 2;
559 } 583 }
560 584
561 585
562 586
563 resource = luaL_checkstring(L, 1); 587 resource = luaL_checkstring(L, 1);
564 rid = string2resource(resource); 588 rid = string2resource(resource);
565 if (rid != -1) { 589
566 if (getrlimit(rid, &lim)) { 590 if(rid != -1) {
591 if(getrlimit(rid, &lim)) {
567 lua_pushboolean(L, 0); 592 lua_pushboolean(L, 0);
568 lua_pushstring(L, "getrlimit-failed."); 593 lua_pushstring(L, "getrlimit-failed.");
569 return 2; 594 return 2;
570 } 595 }
571 } else { 596 } else {
572 /* Unsupported resoucrce. Sorry I'm pretty limited by POSIX standard. */ 597 /* Unsupported resoucrce. Sorry I'm pretty limited by POSIX standard. */
573 lua_pushboolean(L, 0); 598 lua_pushboolean(L, 0);
574 lua_pushstring(L, "invalid-resource"); 599 lua_pushstring(L, "invalid-resource");
575 return 2; 600 return 2;
576 } 601 }
602
577 lua_pushboolean(L, 1); 603 lua_pushboolean(L, 1);
578 if(lim.rlim_cur == RLIM_INFINITY) 604
605 if(lim.rlim_cur == RLIM_INFINITY) {
579 lua_pushstring(L, "unlimited"); 606 lua_pushstring(L, "unlimited");
580 else 607 } else {
581 lua_pushnumber(L, lim.rlim_cur); 608 lua_pushnumber(L, lim.rlim_cur);
582 if(lim.rlim_max == RLIM_INFINITY) 609 }
610
611 if(lim.rlim_max == RLIM_INFINITY) {
583 lua_pushstring(L, "unlimited"); 612 lua_pushstring(L, "unlimited");
584 else 613 } else {
585 lua_pushnumber(L, lim.rlim_max); 614 lua_pushnumber(L, lim.rlim_max);
615 }
616
586 return 3; 617 return 3;
587 } 618 }
588 619
589 int lc_abort(lua_State* L) 620 int lc_abort(lua_State* L) {
590 {
591 abort(); 621 abort();
592 return 0; 622 return 0;
593 } 623 }
594 624
595 int lc_uname(lua_State* L) 625 int lc_uname(lua_State* L) {
596 {
597 struct utsname uname_info; 626 struct utsname uname_info;
598 if(uname(&uname_info) != 0) 627
599 { 628 if(uname(&uname_info) != 0) {
600 lua_pushnil(L); 629 lua_pushnil(L);
601 lua_pushstring(L, strerror(errno)); 630 lua_pushstring(L, strerror(errno));
602 return 2; 631 return 2;
603 } 632 }
633
604 lua_newtable(L); 634 lua_newtable(L);
605 lua_pushstring(L, uname_info.sysname); 635 lua_pushstring(L, uname_info.sysname);
606 lua_setfield(L, -2, "sysname"); 636 lua_setfield(L, -2, "sysname");
607 lua_pushstring(L, uname_info.nodename); 637 lua_pushstring(L, uname_info.nodename);
608 lua_setfield(L, -2, "nodename"); 638 lua_setfield(L, -2, "nodename");
613 lua_pushstring(L, uname_info.machine); 643 lua_pushstring(L, uname_info.machine);
614 lua_setfield(L, -2, "machine"); 644 lua_setfield(L, -2, "machine");
615 return 1; 645 return 1;
616 } 646 }
617 647
618 int lc_setenv(lua_State* L) 648 int lc_setenv(lua_State* L) {
619 { 649 const char* var = luaL_checkstring(L, 1);
620 const char *var = luaL_checkstring(L, 1); 650 const char* value;
621 const char *value;
622 651
623 /* If the second argument is nil or nothing, unset the var */ 652 /* If the second argument is nil or nothing, unset the var */
624 if(lua_isnoneornil(L, 2)) 653 if(lua_isnoneornil(L, 2)) {
625 { 654 if(unsetenv(var) != 0) {
626 if(unsetenv(var) != 0)
627 {
628 lua_pushnil(L); 655 lua_pushnil(L);
629 lua_pushstring(L, strerror(errno)); 656 lua_pushstring(L, strerror(errno));
630 return 2; 657 return 2;
631 } 658 }
659
632 lua_pushboolean(L, 1); 660 lua_pushboolean(L, 1);
633 return 1; 661 return 1;
634 } 662 }
635 663
636 value = luaL_checkstring(L, 2); 664 value = luaL_checkstring(L, 2);
637 665
638 if(setenv(var, value, 1) != 0) 666 if(setenv(var, value, 1) != 0) {
639 {
640 lua_pushnil(L); 667 lua_pushnil(L);
641 lua_pushstring(L, strerror(errno)); 668 lua_pushstring(L, strerror(errno));
642 return 2; 669 return 2;
643 } 670 }
644 671
645 lua_pushboolean(L, 1); 672 lua_pushboolean(L, 1);
646 return 1; 673 return 1;
647 } 674 }
648 675
649 #ifdef WITH_MALLINFO 676 #ifdef WITH_MALLINFO
650 int lc_meminfo(lua_State* L) 677 int lc_meminfo(lua_State* L) {
651 {
652 struct mallinfo info = mallinfo(); 678 struct mallinfo info = mallinfo();
653 lua_newtable(L); 679 lua_newtable(L);
654 /* This is the total size of memory allocated with sbrk by malloc, in bytes. */ 680 /* This is the total size of memory allocated with sbrk by malloc, in bytes. */
655 lua_pushinteger(L, info.arena); 681 lua_pushinteger(L, info.arena);
656 lua_setfield(L, -2, "allocated"); 682 lua_setfield(L, -2, "allocated");
674 /* File handle extraction blatantly stolen from 700 /* File handle extraction blatantly stolen from
675 * https://github.com/rrthomas/luaposix/blob/master/lposix.c#L631 701 * https://github.com/rrthomas/luaposix/blob/master/lposix.c#L631
676 * */ 702 * */
677 703
678 #if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE) 704 #if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L || defined(_GNU_SOURCE)
679 int lc_fallocate(lua_State* L) 705 int lc_fallocate(lua_State* L) {
680 {
681 int ret; 706 int ret;
682 off_t offset, len; 707 off_t offset, len;
683 FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE); 708 FILE* f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE);
684 if (f == NULL) 709
685 luaL_error(L, "attempt to use a closed file"); 710 if(f == NULL) {
711 return luaL_error(L, "attempt to use a closed file");
712 }
686 713
687 offset = luaL_checkinteger(L, 2); 714 offset = luaL_checkinteger(L, 2);
688 len = luaL_checkinteger(L, 3); 715 len = luaL_checkinteger(L, 3);
689 716
690 #if defined(__linux__) && defined(_GNU_SOURCE) 717 #if defined(__linux__) && defined(_GNU_SOURCE)
691 errno = 0; 718 errno = 0;
692 ret = fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len); 719 ret = fallocate(fileno(f), FALLOC_FL_KEEP_SIZE, offset, len);
693 if(ret == 0) 720
694 { 721 if(ret == 0) {
695 lua_pushboolean(L, 1); 722 lua_pushboolean(L, 1);
696 return 1; 723 return 1;
697 } 724 }
725
698 /* Some old versions of Linux apparently use the return value instead of errno */ 726 /* Some old versions of Linux apparently use the return value instead of errno */
699 if(errno == 0) errno = ret; 727 if(errno == 0) {
700 728 errno = ret;
701 if(errno != ENOSYS && errno != EOPNOTSUPP) 729 }
702 { 730
731 if(errno != ENOSYS && errno != EOPNOTSUPP) {
703 lua_pushnil(L); 732 lua_pushnil(L);
704 lua_pushstring(L, strerror(errno)); 733 lua_pushstring(L, strerror(errno));
705 return 2; 734 return 2;
706 } 735 }
736
707 #else 737 #else
708 #warning Only using posix_fallocate() fallback. 738 #warning Only using posix_fallocate() fallback.
709 #warning Linux fallocate() is strongly recommended if available: recompile with -D_GNU_SOURCE 739 #warning Linux fallocate() is strongly recommended if available: recompile with -D_GNU_SOURCE
710 #warning Note that posix_fallocate() will still be used on filesystems that dont support fallocate() 740 #warning Note that posix_fallocate() will still be used on filesystems that dont support fallocate()
711 #endif 741 #endif
712 742
713 ret = posix_fallocate(fileno(f), offset, len); 743 ret = posix_fallocate(fileno(f), offset, len);
714 if(ret == 0) 744
715 { 745 if(ret == 0) {
716 lua_pushboolean(L, 1); 746 lua_pushboolean(L, 1);
717 return 1; 747 return 1;
718 } 748 } else {
719 else
720 {
721 lua_pushnil(L); 749 lua_pushnil(L);
722 lua_pushstring(L, strerror(ret)); 750 lua_pushstring(L, strerror(ret));
723 /* posix_fallocate() can leave a bunch of NULs at the end, so we cut that 751 /* posix_fallocate() can leave a bunch of NULs at the end, so we cut that
724 * this assumes that offset == length of the file */ 752 * this assumes that offset == length of the file */
725 ftruncate(fileno(f), offset); 753 ftruncate(fileno(f), offset);
728 } 756 }
729 #endif 757 #endif
730 758
731 /* Register functions */ 759 /* Register functions */
732 760
733 int luaopen_util_pposix(lua_State *L) 761 int luaopen_util_pposix(lua_State* L) {
734 {
735 luaL_Reg exports[] = { 762 luaL_Reg exports[] = {
736 { "abort", lc_abort }, 763 { "abort", lc_abort },
737 764
738 { "daemonize", lc_daemonize }, 765 { "daemonize", lc_daemonize },
739 766