We were letting services inherit writable fds for /dev/tty0, as well as
having /dev/tty0 as their controlling terminal.
Lock this down by closing fds {0,1,2} when spawning a service. We also
detach from the controlling terminal. An exception is made for services
with an explicit StdIO setting. In those cases, we now switch the
controlling terminal to the specified path if possible.
Also make the sockets readable and writable only by that user.
This fixes a bug where anyone could connect to anyone else's services,
most obviously WindowServer.
Also add error checking and bail out if either call fails.
Doing it the wrong way around was causing us to retain GID=0 for all
processes (oops!)
Thanks to Chris Ball for reporting the bug. :^)
Threads now have numeric priorities with a base priority in the 1-99
range.
Whenever a runnable thread is *not* scheduled, its effective priority
is incremented by 1. This is tracked in Thread::m_extra_priority.
The effective priority of a thread is m_priority + m_extra_priority.
When a runnable thread *is* scheduled, its m_extra_priority is reset to
zero and the effective priority returns to base.
This means that lower-priority threads will always eventually get
scheduled to run, once its effective priority becomes high enough to
exceed the base priority of threads "above" it.
The previous values for ThreadPriority (Low, Normal and High) are now
replaced as follows:
Low -> 10
Normal -> 30
High -> 50
In other words, it will take 20 ticks for a "Low" priority thread to
get to "Normal" effective priority, and another 20 to reach "High".
This is not perfect, and I've used some quite naive data structures,
but I think the mechanism will allow us to build various new and
interesting optimizations, and we can figure out better data structures
later on. :^)
For services explicitly configured as lazy, SystemServer will now listen
on the socket and only spawn the service once a client attempts to connect
to the socket.
SystemServer can now create sockets on behalf of services before spawning any
of them, and pass the open socket fd as fd 3. CLocalServer gains a method to
complete the takeover and listen on the passed fd.
This is not used by any services at the moment.
When reaping a child, SystemServer will now match up child's pid with its own
record of the services, and respawn the service if keepalive is enabled for it.
For example, we want to restart the WindowServer if it crashes, but we wouldn't
want to restart the Terminal if it gets closed.