Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clobbering of MT slots #1439

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ static int openInputDevice(lua_State* L)

// We're done w/ inputdevice, pop it
lua_settop(L, 0);
lua_pushnumber(L, inputfds[fd_idx]);

// Compute select's nfds argument.
// That's not the actual number of fds in the set, like poll(),
Expand All @@ -161,7 +162,7 @@ static int openInputDevice(lua_State* L)
// That, on the other hand, *is* the number of open fds ;).
fd_idx++;

return 0;
return 1;
}

static int closeInputDevices(lua_State* L __attribute__((unused)))
Expand Down Expand Up @@ -203,8 +204,8 @@ static int closeInputDevices(lua_State* L __attribute__((unused)))
static int fakeTapInput(lua_State* L)
{
const char* restrict inputdevice = luaL_checkstring(L, 1);
int x = luaL_checkint(L, 2);
int y = luaL_checkint(L, 3);
int x = luaL_checkint(L, 2);
int y = luaL_checkint(L, 3);

int inputfd = open(inputdevice, O_WRONLY | O_NONBLOCK);
if (inputfd == -1) {
Expand Down Expand Up @@ -271,9 +272,9 @@ static int fakeTapInput(lua_State* L)
return 0;
}

static inline void set_event_table(lua_State* L, const struct input_event* input)
static inline void set_event_table(lua_State* L, const struct input_event* input, int fd)
{
lua_createtable(L, 0, 4); // ev = {} (pre-allocated for its four fields)
lua_createtable(L, 0, 5); // ev = {} (pre-allocated for its five fields)
lua_pushstring(L, "type");
lua_pushinteger(L, input->type); // uint16_t
// NOTE: rawset does t[k] = v, with v @ -1, k @ -2 and t at the specified index, here, that's ev @ -3.
Expand All @@ -286,6 +287,10 @@ static inline void set_event_table(lua_State* L, const struct input_event* input
lua_pushinteger(L, input->value); // int32_t
lua_rawset(L, -3); // ev.value = input.value

lua_pushstring(L, "fd");
lua_pushinteger(L, fd); // int
lua_rawset(L, -3); // ev.fd = fd

lua_pushstring(L, "time");
// NOTE: This is TimeVal-like, but it doesn't feature its metatable!
// The frontend (device/input.lua) will convert it to a proper TimeVal object.
Expand All @@ -299,7 +304,7 @@ static inline void set_event_table(lua_State* L, const struct input_event* input
lua_rawset(L, -3); // ev.time = time
}

static inline size_t drain_input_queue(lua_State* L, struct input_event* input_queue, size_t ev_count, size_t j)
static inline size_t drain_input_queue(lua_State* L, struct input_event* input_queue, size_t ev_count, int fd, size_t j)
{
if (lua_gettop(L) == 1) {
// Only a single element in the stack? (that would be our `true` bool)?
Expand All @@ -312,7 +317,7 @@ static inline size_t drain_input_queue(lua_State* L, struct input_event* input_q

// Iterate over every input event in the queue buffer
for (const struct input_event* event = input_queue; event < input_queue + ev_count; event++) {
set_event_table(L, event); // Pushed a new ev table all filled up at the top of the stack (that's -1)
set_event_table(L, event, fd); // Pushed a new ev table all filled up at the top of the stack (that's -1)
// NOTE: Here, rawseti basically inserts -1 in -2 @ [j]. We ensure that j always points at the tail.
lua_rawseti(L, -2, ++j); // table.insert(ev_array, ev) [, j]
}
Expand Down Expand Up @@ -406,7 +411,7 @@ static int waitForInput(lua_State* L)

if ((size_t) len == queue_available_size) {
// If we're out of buffer space in the queue, drain it *now*
j = drain_input_queue(L, input_queue, ev_count, j);
j = drain_input_queue(L, input_queue, ev_count, inputfds[i], j);
// Rewind to the start of the queue to recycle the buffer
queue_pos = input_queue;
queue_available_size = sizeof(input_queue);
Expand All @@ -418,7 +423,7 @@ static int waitForInput(lua_State* L)
}
}
// We've drained the kernel's input queue, now drain our buffer
j = drain_input_queue(L, input_queue, ev_count, j);
j = drain_input_queue(L, input_queue, ev_count, inputfds[i], j);
return 2; // true, ev_array
}
}
Expand Down