Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70daa670 authored by Viorel Suman's avatar Viorel Suman Committed by Elliott Hughes
Browse files

Multiple consoles

This CL allows enabling of multiple consoles. A service can be
mapped to a specific console by providing the optional argument,
IE "tty0", to "console" service attribute as follows:

service fbconsole /system/bin/sh
    class core
    console tty0
    disabled
    user shell
    group shell log readproc
    seclabel u:r:shell:s0

Bug: None
Change-Id: I3b24e7f6848bbe5c6475f11334c04ec536e6af88
Tracked-On: https://jira01.devtools.intel.com/browse/BP-289


Signed-off-by: default avatarViorel Suman <viorel.suman@intel.com>
parent ba443831
Loading
Loading
Loading
Loading
+2 −31
Original line number Diff line number Diff line
@@ -74,8 +74,7 @@ static int property_triggers_enabled = 0;

static char qemu[32];

int have_console;
std::string console_name = "/dev/console";
std::string default_console = "/dev/console";
static time_t process_needs_restart;

const char *ENV[32];
@@ -300,36 +299,8 @@ static int console_init_action(const std::vector<std::string>& args)
{
    std::string console = property_get("ro.boot.console");
    if (!console.empty()) {
        console_name = "/dev/" + console;
    }

    int fd = open(console_name.c_str(), O_RDWR | O_CLOEXEC);
    if (fd >= 0)
        have_console = 1;
    close(fd);

    fd = open("/dev/tty0", O_WRONLY | O_CLOEXEC);
    if (fd >= 0) {
        const char *msg;
            msg = "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"  // console is 40 cols x 30 lines
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "             A N D R O I D ";
        write(fd, msg, strlen(msg));
        close(fd);
        default_console = "/dev/" + console;
    }

    return 0;
}

+1 −2
Original line number Diff line number Diff line
@@ -26,8 +26,7 @@ class Service;

extern const char *ENV[32];
extern bool waiting_for_exec;
extern int have_console;
extern std::string console_name;
extern std::string default_console;
extern struct selabel_handle *sehandle;
extern struct selabel_handle *sehandle_prop;

+7 −0
Original line number Diff line number Diff line
@@ -115,6 +115,13 @@ Options
Options are modifiers to services.  They affect how and when init
runs the service.

console [<console>]
  This service needs a console. The optional second parameter chooses a
  specific console instead of the default. The default "/dev/console" can
  be changed by setting the "androidboot.console" kernel parameter. In
  all cases the leading "/dev/" should be omitted, so "/dev/tty0" would be
  specified as just "console tty0".

critical
  This is a device-critical service. If it exits more than four times in
  four minutes, the device will reboot into recovery mode.
+16 −9
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ bool Service::HandleClass(const std::vector<std::string>& args, std::string* err

bool Service::HandleConsole(const std::vector<std::string>& args, std::string* err) {
    flags_ |= SVC_CONSOLE;
    console_ = args.size() > 1 ? "/dev/" + args[1] : "";
    return true;
}

@@ -282,7 +283,7 @@ Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map() const {
    constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
    static const Map option_handlers = {
        {"class",       {1,     1,    &Service::HandleClass}},
        {"console",     {0,     0,    &Service::HandleConsole}},
        {"console",     {0,     1,    &Service::HandleConsole}},
        {"critical",    {0,     0,    &Service::HandleCritical}},
        {"disabled",    {0,     0,    &Service::HandleDisabled}},
        {"group",       {1,     NR_SVC_SUPP_GIDS + 1, &Service::HandleGroup}},
@@ -329,11 +330,19 @@ bool Service::Start(const std::vector<std::string>& dynamic_args) {
    }

    bool needs_console = (flags_ & SVC_CONSOLE);
    if (needs_console && !have_console) {
        ERROR("service '%s' requires console\n", name_.c_str());
    if (needs_console) {
        if (console_.empty()) {
            console_ = default_console;
        }

        bool have_console = (open(console_.c_str(), O_RDWR | O_CLOEXEC) != -1);
        if (!have_console) {
            ERROR("service '%s' couldn't open console '%s': %s\n",
                  name_.c_str(), console_.c_str(), strerror(errno));
            flags_ |= SVC_DISABLED;
            return false;
        }
    }

    struct stat sb;
    if (stat(args_[0].c_str(), &sb) == -1) {
@@ -606,10 +615,8 @@ void Service::ZapStdio() const {
}

void Service::OpenConsole() const {
    int fd;
    if ((fd = open(console_name.c_str(), O_RDWR)) < 0) {
        fd = open("/dev/null", O_RDWR);
    }
    int fd = open(console_.c_str(), O_RDWR);
    if (fd == -1) fd = open("/dev/null", O_RDWR);
    ioctl(fd, TIOCSCTTY, 0);
    dup2(fd, 0);
    dup2(fd, 1);
+1 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ private:

    std::string name_;
    std::string classname_;
    std::string console_;

    unsigned flags_;
    pid_t pid_;