Software / code / prosody
Comparison
util-src/pposix.c @ 5719:84025249fc04
util.pposix: Correctly handle 'unlimited' limits (RLIM_INFINITY), by returning and accepting the string 'unlimited' in get/setrlimit()
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sat, 29 Jun 2013 14:45:38 +0100 |
| parent | 5451:941ad88db8f3 |
| child | 5720:449399a7e136 |
comparison
equal
deleted
inserted
replaced
| 5716:8a0465de172e | 5719:84025249fc04 |
|---|---|
| 489 if (!strcmp(s, "NICE")) return RLIMIT_NICE; | 489 if (!strcmp(s, "NICE")) return RLIMIT_NICE; |
| 490 #endif | 490 #endif |
| 491 return -1; | 491 return -1; |
| 492 } | 492 } |
| 493 | 493 |
| 494 int arg_to_rlimit(lua_State* L, int idx, rlim_t current) { | |
| 495 switch(lua_type(L, idx)) { | |
| 496 case LUA_TSTRING: | |
| 497 if(strcmp(lua_tostring(L, idx), "unlimited") == 0) | |
| 498 return RLIM_INFINITY; | |
| 499 case LUA_TNUMBER: | |
| 500 return lua_tointeger(L, idx); | |
| 501 case LUA_TNONE: | |
| 502 case LUA_TNIL: | |
| 503 return current; | |
| 504 default: | |
| 505 return luaL_argerror(L, idx, "unexpected type"); | |
| 506 } | |
| 507 } | |
| 508 | |
| 494 int lc_setrlimit(lua_State *L) { | 509 int lc_setrlimit(lua_State *L) { |
| 510 struct rlimit lim; | |
| 495 int arguments = lua_gettop(L); | 511 int arguments = lua_gettop(L); |
| 496 int softlimit = -1; | |
| 497 int hardlimit = -1; | |
| 498 const char *resource = NULL; | |
| 499 int rid = -1; | 512 int rid = -1; |
| 500 if(arguments < 1 || arguments > 3) { | 513 if(arguments < 1 || arguments > 3) { |
| 501 lua_pushboolean(L, 0); | 514 lua_pushboolean(L, 0); |
| 502 lua_pushstring(L, "incorrect-arguments"); | 515 lua_pushstring(L, "incorrect-arguments"); |
| 503 } | 516 return 2; |
| 504 | 517 } |
| 505 resource = luaL_checkstring(L, 1); | 518 |
| 506 softlimit = luaL_checkinteger(L, 2); | 519 rid = string2resource(luaL_checkstring(L, 1)); |
| 507 hardlimit = luaL_checkinteger(L, 3); | 520 if (rid == -1) { |
| 508 | |
| 509 rid = string2resource(resource); | |
| 510 if (rid != -1) { | |
| 511 struct rlimit lim; | |
| 512 struct rlimit lim_current; | |
| 513 | |
| 514 if (softlimit < 0 || hardlimit < 0) { | |
| 515 if (getrlimit(rid, &lim_current)) { | |
| 516 lua_pushboolean(L, 0); | |
| 517 lua_pushstring(L, "getrlimit-failed"); | |
| 518 return 2; | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 if (softlimit < 0) lim.rlim_cur = lim_current.rlim_cur; | |
| 523 else lim.rlim_cur = softlimit; | |
| 524 if (hardlimit < 0) lim.rlim_max = lim_current.rlim_max; | |
| 525 else lim.rlim_max = hardlimit; | |
| 526 | |
| 527 if (setrlimit(rid, &lim)) { | |
| 528 lua_pushboolean(L, 0); | |
| 529 lua_pushstring(L, "setrlimit-failed"); | |
| 530 return 2; | |
| 531 } | |
| 532 } else { | |
| 533 /* Unsupported resoucrce. Sorry I'm pretty limited by POSIX standard. */ | |
| 534 lua_pushboolean(L, 0); | 521 lua_pushboolean(L, 0); |
| 535 lua_pushstring(L, "invalid-resource"); | 522 lua_pushstring(L, "invalid-resource"); |
| 523 return 2; | |
| 524 } | |
| 525 | |
| 526 /* Fetch current values to use as defaults */ | |
| 527 if (getrlimit(rid, &lim)) { | |
| 528 lua_pushboolean(L, 0); | |
| 529 lua_pushstring(L, "getrlimit-failed"); | |
| 530 return 2; | |
| 531 } | |
| 532 | |
| 533 lim.rlim_cur = arg_to_rlimit(L, 2, lim.rlim_cur); | |
| 534 lim.rlim_max = arg_to_rlimit(L, 3, lim.rlim_max); | |
| 535 | |
| 536 if (setrlimit(rid, &lim)) { | |
| 537 lua_pushboolean(L, 0); | |
| 538 lua_pushstring(L, "setrlimit-failed"); | |
| 536 return 2; | 539 return 2; |
| 537 } | 540 } |
| 538 lua_pushboolean(L, 1); | 541 lua_pushboolean(L, 1); |
| 539 return 1; | 542 return 1; |
| 540 } | 543 } |
| 548 if (arguments != 1) { | 551 if (arguments != 1) { |
| 549 lua_pushboolean(L, 0); | 552 lua_pushboolean(L, 0); |
| 550 lua_pushstring(L, "invalid-arguments"); | 553 lua_pushstring(L, "invalid-arguments"); |
| 551 return 2; | 554 return 2; |
| 552 } | 555 } |
| 556 | |
| 557 | |
| 553 | 558 |
| 554 resource = luaL_checkstring(L, 1); | 559 resource = luaL_checkstring(L, 1); |
| 555 rid = string2resource(resource); | 560 rid = string2resource(resource); |
| 556 if (rid != -1) { | 561 if (rid != -1) { |
| 557 if (getrlimit(rid, &lim)) { | 562 if (getrlimit(rid, &lim)) { |
| 564 lua_pushboolean(L, 0); | 569 lua_pushboolean(L, 0); |
| 565 lua_pushstring(L, "invalid-resource"); | 570 lua_pushstring(L, "invalid-resource"); |
| 566 return 2; | 571 return 2; |
| 567 } | 572 } |
| 568 lua_pushboolean(L, 1); | 573 lua_pushboolean(L, 1); |
| 569 lua_pushnumber(L, lim.rlim_cur); | 574 if(lim.rlim_cur == RLIM_INFINITY) |
| 570 lua_pushnumber(L, lim.rlim_max); | 575 lua_pushstring(L, "unlimited"); |
| 576 else | |
| 577 lua_pushnumber(L, lim.rlim_cur); | |
| 578 if(lim.rlim_max == RLIM_INFINITY) | |
| 579 lua_pushstring(L, "unlimited"); | |
| 580 else | |
| 581 lua_pushnumber(L, lim.rlim_max); | |
| 571 return 3; | 582 return 3; |
| 572 } | 583 } |
| 573 | 584 |
| 574 int lc_abort(lua_State* L) | 585 int lc_abort(lua_State* L) |
| 575 { | 586 { |