Teminal: fix crash when grantpt or unlockpt fail (#8845)

* Fix crash when grantpt or unlockpt fail
* Disable plugin if grantpt or unlockpt fail
reviewable/pr8847/r1
zwim 2 years ago committed by GitHub
parent ee593e6b17
commit 1cd396f9c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,11 +5,43 @@ This plugin provides a terminal emulator (VT52 (+some ANSI))
]]
local Device = require("device")
local ffi = require("ffi")
local C = ffi.C
-- for terminal emulator
ffi.cdef[[
static const int SIGTERM = 15;
int grantpt(int fd) __attribute__((nothrow, leaf));
int unlockpt(int fd) __attribute__((nothrow, leaf));
char *ptsname(int fd) __attribute__((nothrow, leaf));
pid_t setsid(void) __attribute__((nothrow, leaf));
static const int TCIFLUSH = 0;
int tcdrain(int fd) __attribute__((nothrow, leaf));
int tcflush(int fd, int queue_selector) __attribute__((nothrow, leaf));
]]
local function check_prerequisites()
local ptmx_name = "/dev/ptmx"
local ptmx = C.open(ptmx_name, bit.bor(C.O_RDWR, C.O_NONBLOCK, C.O_CLOEXEC))
if C.grantpt(ptmx) ~= 0 then
C.close(ptmx)
return false
end
if C.unlockpt(ptmx) ~= 0 then
C.close(ptmx)
return false
end
C.close(ptmx)
return true
end
-- grantpt and friends are necessary (introduced on Android in API 21).
-- So sorry for the Tolinos with (Android 4.4.x).
-- Maybe https://f-droid.org/de/packages/jackpal.androidterm/ could be an alternative then.
if Device:isAndroid() and Device.firmware_rev < 21 then
if (Device:isAndroid() and Device.firmware_rev < 21) or not check_prerequisites() then
return
end
@ -32,23 +64,6 @@ local logger = require("logger")
local _ = require("gettext")
local T = require("ffi/util").template
local ffi = require("ffi")
local C = ffi.C
-- for terminal emulator
ffi.cdef[[
static const int SIGTERM = 15;
int grantpt(int fd) __attribute__((nothrow, leaf));
int unlockpt(int fd) __attribute__((nothrow, leaf));
char *ptsname(int fd) __attribute__((nothrow, leaf));
pid_t setsid(void) __attribute__((nothrow, leaf));
static const int TCIFLUSH = 0;
int tcdrain(int fd) __attribute__((nothrow, leaf));
int tcflush(int fd, int queue_selector) __attribute__((nothrow, leaf));
]]
local CHUNK_SIZE = 80 * 40 -- max. nb of read bytes (reduce this, if taps are not detected)
local Terminal = WidgetContainer:new{
@ -86,9 +101,13 @@ function Terminal:spawnShell(cols, rows)
if C.grantpt(self.ptmx) ~= 0 then
logger.err("Terminal: can not grantpt")
C.close(self.ptmx)
return false
end
if C.unlockpt(self.ptmx) ~= 0 then
logger.err("Terminal: can not unockpt")
C.close(self.ptmx)
return false
end
self.slave_pty = ffi.string(C.ptsname(self.ptmx))
@ -155,6 +174,7 @@ function Terminal:spawnShell(cols, rows)
self.input_widget:interpretAnsiSeq(self:receive())
logger.info("Terminal: spawn done")
return true
end
function Terminal:receive()
@ -409,10 +429,11 @@ function Terminal:onTerminalStart(touchmenu_instance)
logger.dbg("Terminal: resolution= " .. self.maxc .. "x" .. self.maxr)
self:spawnShell(self.maxc, self.maxr)
UIManager:show(self.input_dialog)
UIManager:scheduleIn(0.25, Terminal.refresh, self, true)
self.input_dialog:onShowKeyboard(true)
if self:spawnShell(self.maxc, self.maxr) then
UIManager:show(self.input_dialog)
UIManager:scheduleIn(0.25, Terminal.refresh, self, true)
self.input_dialog:onShowKeyboard(true)
end
end
function Terminal:addToMainMenu(menu_items)

Loading…
Cancel
Save