return pid
end
+--- Forkpty. Like fork but open a PTY.
+-- @return PID of child or false on error. PID of 0 means child process.
+-- @return File Descriptor for pseudo terminal (parent only).
+-- Error object on failure.
+-- @return Path to PTY device node.
+function e2lib.forkpty()
+ local rc, re
+ local pid, fdm, ptyname
+
+ pid, fdm, ptyname = le2lib.forkpty()
+ if not pid then
+ return false, err.new("failed to fork new pty: %s", fdm)
+ end
+ if pid == 0 then
+ -- child, return early
+ return pid
+ end
+
+ assert(type(fdm) == "number")
+ assert(type(ptyname) == "string")
+
+ return pid, fdm, ptyname
+end
+
--- Set umask value.
-- @param mask New umask value.
-- @return Previous umask value.
#include <poll.h>
#include <fcntl.h>
#include <ctype.h>
+#include <pty.h>
#include <lua.h>
#include <lualib.h>
return 2;
}
+static int
+do_forkpty(lua_State *L)
+{
+ int cpid, fdm;
+ char ptyname[PATH_MAX];
+
+ cpid = forkpty(&fdm, ptyname, NULL, NULL);
+ if (cpid < 0) {
+ lua_pushboolean(L, 0);
+ lua_pushstring(L, strerror(errno));
+ return 2;
+ }
+
+ lua_pushnumber(L, cpid);
+ if (cpid == 0)
+ return 1;
+
+ lua_pushnumber(L, fdm);
+ lua_pushstring(L, ptyname);
+
+ return 3;
+}
+
static luaL_Reg lib[] = {
{ "chdir", change_directory },
{ "chmod", do_chmod },
{ "execvp", do_execvp },
{ "exists", file_exists },
{ "fork", lua_fork },
+ { "forkpty", do_forkpty },
{ "getpid", do_getpid },
{ "hardlink", do_hardlink },
{ "kill", do_kill },