diff --git a/base b/base index 65d3ee1e4..7b05d5a73 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 65d3ee1e46a595da2adfde97f7e941567dc522d0 +Subproject commit 7b05d5a73980f852290e3f10e6078cc88162bbea diff --git a/frontend/dbg.lua b/frontend/dbg.lua index cadd011c5..c94a8809b 100644 --- a/frontend/dbg.lua +++ b/frontend/dbg.lua @@ -52,9 +52,15 @@ function Dbg:turnOn() return check end - --- @todo close ev.log fd for children -- create or clear ev log file - self.ev_log = io.open("ev.log", "w") + --- @note: On Linux, use CLOEXEC to avoid polluting the fd table of our child processes. + --- Otherwise, it can be problematic w/ wpa_supplicant & USBMS... + --- Note that this is entirely undocumented, but at least LuaJIT passes the mode as-is to fopen, so, we're good. + if jit.os == "Linux" then + self.ev_log = io.open("ev.log", "we") + else + self.ev_log = io.open("ev.log", "w") + end end function Dbg:turnOff() diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 6339966da..b32178f47 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -48,6 +48,7 @@ local Kobo = Generic:new{ -- HW inversion is generally safe on Kobo, except on a few boards/kernels canHWInvert = yes, home_dir = "/mnt/onboard", + canToggleMassStorage = yes, } --- @todo hasKeys for some devices? diff --git a/frontend/ui/elements/mass_storage.lua b/frontend/ui/elements/mass_storage.lua index 6665c2e17..1cf35e01c 100644 --- a/frontend/ui/elements/mass_storage.lua +++ b/frontend/ui/elements/mass_storage.lua @@ -13,6 +13,7 @@ function MassStorage:getSettingsMenuTable() return { { text = _("Disable confirmation popup"), + help_text = _([[This will NOT affect what happens when you simply plug in the device!]]), checked_func = function() return not self:requireConfirmation() end, callback = function() G_reader_settings:saveSetting("mass_storage_confirmation_disabled", self:requireConfirmation()) @@ -34,11 +35,11 @@ function MassStorage:getActionsMenuTable() end -- exit KOReader and start mass storage mode. -function MassStorage:start() - if self:requireConfirmation() then +function MassStorage:start(always_ask) + if self:requireConfirmation() or always_ask then local ConfirmBox = require("ui/widget/confirmbox") UIManager:show(ConfirmBox:new{ - text = _("Share storage via USB?\n"), + text = _("Share storage via USB?"), ok_text = _("Share"), ok_callback = function() UIManager:quit() diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 786fa0f71..26c854564 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -155,8 +155,13 @@ function UIManager:init() end self.event_handlers["Charging"] = function() self:_beforeCharging() + -- NOTE: Plug/unplug events will wake the device up, which is why we put it back to sleep. if Device.screen_saver_mode then self:suspend() + else + -- Potentially start an USBMS session + local MassStorage = require("ui/elements/mass_storage") + MassStorage:start(true) end end self.event_handlers["NotCharging"] = function() diff --git a/platform/kobo/enable-wifi.sh b/platform/kobo/enable-wifi.sh index 733d97267..41d293253 100755 --- a/platform/kobo/enable-wifi.sh +++ b/platform/kobo/enable-wifi.sh @@ -1,5 +1,18 @@ #!/bin/sh +# NOTE: Close any non-standard fds, so that it doesn't come back to bite us in the ass with USBMS later... +for fd in /proc/"$$"/fd/*; do + fd_id="$(basename "${fd}")" + if [ -e "${fd}" ] && [ "${fd_id}" -gt 2 ]; then + # NOTE: dash (meaning, in turn, busybox's ash, uses fd 10+ open to /dev/tty or $0 (w/ CLOEXEC)) + fd_path="$(readlink -f "${fd}")" + if [ "${fd_path}" != "/dev/tty" ] && [ "${fd_path}" != "$(readlink -f "${0}")" ] && [ "${fd}" != "${fd_path}" ]; then + eval "exec ${fd_id}>&-" + echo "[enable-wifi.sh] Closed fd ${fd_id} -> ${fd_path}" + fi + fi +done + # Load wifi modules and enable wifi. lsmod | grep -q sdio_wifi_pwr || insmod "/drivers/${PLATFORM}/wifi/sdio_wifi_pwr.ko" # Moar sleep! diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index fe86403bf..c9cceaff8 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -2,11 +2,20 @@ export LC_ALL="en_US.UTF-8" # Compute our working directory in an extremely defensive manner -KOREADER_DIR="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)" +SCRIPT_DIR="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P)" +# NOTE: We need to remember the *actual* KOREADER_DIR, not the relocalized version in /tmp... +export KOREADER_DIR="${KOREADER_DIR:-${SCRIPT_DIR}}" # We rely on starting from our working directory, and it needs to be set, sane and absolute. cd "${KOREADER_DIR:-/dev/null}" || exit +# To make USBMS behave, relocalize ourselves outside of onboard +if [ "${SCRIPT_DIR}" != "/tmp" ]; then + cp -pf "${0}" "/tmp/koreader.sh" + chmod 777 "/tmp/koreader.sh" + exec "/tmp/koreader.sh" "$@" +fi + # Attempt to switch to a sensible CPUFreq governor when that's not already the case... IFS= read -r current_cpufreq_gov <"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" # NOTE: We're being fairly conservative here, because what's used and what's available varies depending on HW... @@ -249,11 +258,13 @@ fi CRASH_COUNT=0 CRASH_TS=0 CRASH_PREV_TS=0 +# List of supported special return codes +KO_RC_RESTART=85 +KO_RC_USBMS=86 # Because we *want* an initial fbdepth pass ;). -RETURN_VALUE=85 +RETURN_VALUE=${KO_RC_RESTART} while [ ${RETURN_VALUE} -ne 0 ]; do - # 85 is what we return when asking for a KOReader restart - if [ ${RETURN_VALUE} -eq 85 ]; then + if [ ${RETURN_VALUE} -eq ${KO_RC_RESTART} ]; then # Do an update check now, so we can actually update KOReader via the "Restart KOReader" menu entry ;). ko_update_check # Do or double-check the fb depth switch, or restore original bitdepth if requested @@ -266,7 +277,7 @@ while [ ${RETURN_VALUE} -ne 0 ]; do RETURN_VALUE=$? # Did we crash? - if [ ${RETURN_VALUE} -ne 0 ] && [ ${RETURN_VALUE} -ne 85 ]; then + if [ ${RETURN_VALUE} -ne 0 ] && [ ${RETURN_VALUE} -ne ${KO_RC_RESTART} ] && [ ${RETURN_VALUE} -ne ${KO_RC_USBMS} ]; then # Increment the crash counter CRASH_COUNT=$((CRASH_COUNT + 1)) CRASH_TS=$(date +'%s') @@ -348,6 +359,24 @@ while [ ${RETURN_VALUE} -ne 0 ]; do # Reset the crash counter if that was a sane exit/restart CRASH_COUNT=0 fi + + if [ ${RETURN_VALUE} -eq ${KO_RC_USBMS} ]; then + # User requested an USBMS session, setup the tool outside of onboard + mkdir -p "/tmp/usbms" + ./tar xzf "./data/KoboUSBMS.tar.gz" -C "/tmp/usbms" + + # Here we go! + cd "/tmp/usbms" || continue + if ! ./usbms; then + # Hu, oh, something went wrong... Stay around for 90s (enough time to look at the syslog over Wi-Fi), and then shutdown. + sleep 90 + poweroff -f + fi + + # Jump back to the right place, and keep on trucking + cd "${KOREADER_DIR}" || poweroff -f + rm -rf "/tmp/usbms" + fi done # Restore original fb bitdepth if need be... @@ -388,4 +417,7 @@ else fi fi +# Wipe the clones on exit +rm -f "/tmp/koreader.sh" + exit ${RETURN_VALUE} diff --git a/platform/kobo/nickel.sh b/platform/kobo/nickel.sh index 8e7f67331..081c02ac4 100755 --- a/platform/kobo/nickel.sh +++ b/platform/kobo/nickel.sh @@ -11,7 +11,7 @@ export LD_LIBRARY_PATH="/usr/local/Kobo" cd / unset OLDPWD unset LC_ALL TESSDATA_PREFIX STARDICT_DATA_DIR EXT_FONT_DIR -unset KO_NO_CBB +unset KOREADER_DIR KO_NO_CBB # Ensures fmon will restart. Note that we don't have to worry about reaping this, nickel kills on-animator.sh on start. ( diff --git a/platform/kobo/obtain-ip.sh b/platform/kobo/obtain-ip.sh index fd4dca469..4b9e3e456 100755 --- a/platform/kobo/obtain-ip.sh +++ b/platform/kobo/obtain-ip.sh @@ -1,5 +1,18 @@ #!/bin/sh +# NOTE: Close any non-standard fds, so that it doesn't come back to bite us in the ass with USBMS later... +for fd in /proc/"$$"/fd/*; do + fd_id="$(basename "${fd}")" + if [ -e "${fd}" ] && [ "${fd_id}" -gt 2 ]; then + # NOTE: dash (meaning, in turn, busybox's ash, uses fd 10+ open to /dev/tty or $0 (w/ CLOEXEC)) + fd_path="$(readlink -f "${fd}")" + if [ "${fd_path}" != "/dev/tty" ] && [ "${fd_path}" != "$(readlink -f "${0}")" ] && [ "${fd}" != "${fd_path}" ]; then + eval "exec ${fd_id}>&-" + echo "[obtain-ip.sh] Closed fd ${fd_id} -> ${fd_path}" + fi + fi +done + ./release-ip.sh # NOTE: Prefer dhcpcd over udhcpc if available. That's what Nickel uses,