return rc, childpid, sig
end
---- Poll input output multiplexing.
--- Only indicates first selected file descriptor.
+--- Poll input output multiplexing. See poll(2) for details on flags etc.
-- @param timeout Timeout in milliseconds (number).
--- @param fdvec Vector of file descriptors (table of numbers).
--- @return Returns 0 on timeout, < 0 on error and > 0 for the position in fdvec
--- that has an event waiting.
--- @return True if it's a POLLIN event.
--- @return True if it's a POLLOUT event.
+-- @param fdvec Vector of file descriptors. This wrapper listens for
+-- POLLIN and POLLOUT events on every fd.
+-- @return False on error, empty table on timeout, or a vector of tables for
+-- each selected file descriptor. The tables looks like this:
+-- { fd=(file descriptor number), fdvecpos=(index number),
+-- POLLIN=boolean, POLLOUT=boolean }.
+-- If a file descriptor is selected but neither POLLIN nor POLLOUT are
+-- set, the file descriptor was closed. fdvecpos is the position of the
+-- fd in the fdvec table.
+-- @return Error object on failure.
function e2lib.poll(timeout, fdvec)
- return le2lib.poll(timeout, fdvec)
+ local pollvec, errstring
+
+ pollvec, errstring = le2lib.poll(timeout, fdvec)
+ if not pollvec then
+ return false, err.new("poll() failed: %s", errstring)
+ end
+
+ return pollvec
end
--- Set file descriptor in non-blocking mode.
poll_fd(lua_State *lua)
{
int tmo = luaL_checkinteger(lua, 1);
- int nfds = 0, f;
+ int nfds = 0, f, index = 0;
struct pollfd *fds = NULL;
luaL_checktype(lua, 2, LUA_TTABLE);
nfds += 1;
}
f = poll(fds, nfds, tmo);
+ if (f < 0) {
+ lua_pushboolean(lua, 0);
+ lua_pushstring(lua, strerror(errno));
+ return 2;
+ }
- if (f > 0) {
- while (--nfds >= 0) {
- if (fds[nfds].revents) {
- lua_pushnumber(lua, nfds+1);
- lua_pushboolean(lua, fds[nfds].revents & POLLIN);
- lua_pushboolean(lua, fds[nfds].revents & POLLOUT);
- free(fds);
- return 3;
- }
+ /* We want to return a table containing all selected fds looking like
+ * this:
+ * {
+ * { fd = 3, fdvecpos=1, POLLIN = true, POLLOUT = false },
+ * { fd = 5, fdvecpos=2, POLLIN = false, POLLOUT = false },
+ * ...
+ * }
+ */
+
+ lua_newtable(lua);
+
+ while (index < f && --nfds >= 0) {
+ if (fds[nfds].revents) {
+ lua_createtable(lua, 0, 4); /* 4 elements */
+
+ lua_pushliteral(lua, "fd");
+ lua_pushnumber(lua, fds[nfds].fd);
+ lua_rawset(lua, -3);
+
+ lua_pushliteral(lua, "fdvecpos");
+ lua_pushnumber(lua, nfds+1);
+ lua_rawset(lua, -3);
+
+ lua_pushliteral(lua, "POLLIN");
+ lua_pushboolean(lua, fds[nfds].revents & POLLIN);
+ lua_rawset(lua, -3);
+
+ lua_pushliteral(lua, "POLLOUT");
+ lua_pushboolean(lua, fds[nfds].revents & POLLOUT);
+ lua_rawset(lua, -3);
+
+ /* commit table to newtable at index */
+ lua_rawseti(lua, -2, ++index);
}
}
+
free(fds);
- lua_pushnumber(lua, f);
return 1;
}