Skip to content

Commit 29e8e40

Browse files
Physic69lneto
authored andcommitted
Add signal functions (sigmodify, pending)
1 parent 4c7cc53 commit 29e8e40

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

lib/lualinux.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,93 @@ static int lualinux_schedule(lua_State *L)
120120
return 1;
121121
}
122122

123+
/***
124+
* Modifies signal mask for current task.
125+
*
126+
* @function sigmask
127+
* @tparam integer sig Signal number
128+
* @tparam[opt] integer cmd 0=BLOCK (default), 1=UNBLOCK
129+
* @raise error string on failure (EINVAL, EPERM, etc.)
130+
* @within linux
131+
* @usage
132+
* pcall(linux.sigmask, 15) -- Block SIGTERM
133+
* pcall(linux.sigmask, 15, 1) -- Unblock SIGTERM
134+
*/
135+
static int lualinux_sigmask(lua_State *L)
136+
{
137+
sigset_t newmask;
138+
sigemptyset(&newmask);
139+
140+
int signum = luaL_checkinteger(L, 1);
141+
int cmd = luaL_optinteger(L, 2, 0);
142+
143+
sigaddset(&newmask, signum);
144+
145+
lunatik_try(L, sigprocmask, cmd, &newmask, NULL);
146+
return 0;
147+
}
148+
149+
/***
150+
* Checks current task pending signals.
151+
*
152+
* @function sigpending
153+
* @treturn boolean
154+
* @within linux
155+
* @usage
156+
* linux.sigpending()
157+
*/
158+
static int lualinux_sigpending(lua_State *L)
159+
{
160+
lua_pushboolean(L, signal_pending(current));
161+
return 1;
162+
}
163+
164+
/***
165+
* Checks signal state for current task.
166+
*
167+
* @function sigstate
168+
* @tparam integer sig Signal number
169+
* @tparam[opt] string state One of: "blocked", "pending", "allowed"
170+
* @treturn boolean
171+
* @within linux
172+
* @usage
173+
* linux.sigstate(15) -- check if SIGTERM is blocked (default)
174+
* linux.sigstate(linux.signal.TERM, "pending")
175+
*/
176+
static int lualinux_sigstate(lua_State *L)
177+
{
178+
enum sigstate_cmd {
179+
SIGSTATE_BLOCKED,
180+
SIGSTATE_PENDING,
181+
SIGSTATE_ALLOWED,
182+
};
183+
184+
const char *const sigstate_opts[] = {
185+
[SIGSTATE_BLOCKED] = "blocked",
186+
[SIGSTATE_PENDING] = "pending",
187+
[SIGSTATE_ALLOWED] = "allowed",
188+
};
189+
190+
int signum = luaL_checkinteger(L, 1);
191+
enum sigstate_cmd cmd = (enum sigstate_cmd)luaL_checkoption(L, 2, "blocked", sigstate_opts);
192+
193+
bool result;
194+
switch (cmd) {
195+
case SIGSTATE_BLOCKED:
196+
result = sigismember(&current->blocked, signum);
197+
break;
198+
case SIGSTATE_PENDING:
199+
result = sigismember(&current->pending.signal, signum);
200+
break;
201+
case SIGSTATE_ALLOWED:
202+
result = !sigismember(&current->blocked, signum);
203+
break;
204+
}
205+
206+
lua_pushboolean(L, result);
207+
return 1;
208+
}
209+
123210
/***
124211
* Kills a process by sending a signal.
125212
* By default, sends SIGKILL.
@@ -591,6 +678,9 @@ static const lunatik_namespace_t lualinux_flags[] = {
591678
static const luaL_Reg lualinux_lib[] = {
592679
{"random", lualinux_random},
593680
{"schedule", lualinux_schedule},
681+
{"sigmask", lualinux_sigmask},
682+
{"sigpending", lualinux_sigpending},
683+
{"sigstate", lualinux_sigstate},
594684
{"kill", lualinux_kill},
595685
{"tracing", lualinux_tracing},
596686
{"time", lualinux_time},

0 commit comments

Comments
 (0)