Allow to send arbitrary signals to the foreground process group of the
pty. Linux supports the TIOCSIG ioctl so we actually do not need to
implement this on our own, yeah!
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
We shouldn't call the close-cb twice. Therefore, correctly free the FD on
first error, however, keep the signal-callback to get nice log-messages.
Only when the user calls *_close() we eventually stop everything.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
We currently return "ret" when child setup fails, however, we should
rather call exit(). Also avoid cleaning up as this is impossible here
anyway.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
We should do fork() as the last operation when starting the child.
Currently, if our eloop-add() fails, we have a started child but return
failure to the caller. Therefore, the child will stay alive but we do not
use it.
We now perform all startup correctly before fork()'ing so we are always
safe when starting the child.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
pthread is already in our vmem due to our dependencies so link to it
explicitly and use pthread_sigmask to avoid buggy sigprocmask in
multi-threaded applications.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Allow to specify a separate login-program that is executed instead of the
default. All arguments specified after --login are considered argv[] of
the new process and not parsed by the library.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
config.h is meant to be around in all files, as it contains stuff like
_GNU_SOURCE, NDEBUG and HAVE_*.
Make these definitions available without needing to #include config.h
every single time.
Signed-off-by: Ran Benita <ran234@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Allocate the IO-buffer dynamically on the heap for every pty object to
avoid 4KB objects on the stack. This may not be a problem now but we
might get stack overflows later if we continue to use such huge arrays
on the stack.
This doesn't affect the runtime performance as the buffer is still
allocated only once on pty-creation.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Increase the buffer size to match the kernel's. This should guarantee
(practically) that we read() everything queued up for us.
This speeds us up considerably when running something like
$ find /
Such a process spends most of its time blocking on write() waiting for
us. By increasing the buffer size we avoid repeated
read pty -> draw screen -> read pty
cycles, which take most of our time.
To time it, before:
real 0m22.588s
user 0m00.000s
sys 0m00.020s
After:
real 0m00.680s
user 0m00.023s
sys 0m00.000s
Signed-off-by: Ran Benita <ran234@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
The name fork_pty_child was misleading. It doesn't fork at all but
instead sets up the child's environment.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This ioctl is really not needed and performs needles kernel context
switches. We can simply read into our buffer without checking how many
data is available.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
If the child returns EWOULDBLOCK on write we need to save the input in a
buffer to avoid loosing data. We need to work in non-blocking mode to
avoid UI hangs so we simply use the new ring-buffer object to store
data.
This also changes the callback behavior. The pty is no longer closed
implicitely so the owner must call pty_close now even if the close
callback is called. This avoids circular callbacks.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
There is no reason to keep two callbacks as the caller always registers
both. Hence, we can use a shared callback. Reading length 0 means closed
like reading from an fd.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
There is no reason to pass the eloop reference late at terminal/pty
open. If we pass it early on object creation we will always have a valid
reference and can remove several code paths.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
The output_cb handles output from the pty but it actually makes more
sense to call it input_cb as we are handling input to our console here.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
pty_write actually makes more sense as we are writing to the other end
and not reading input.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
When we register signals in the eloop we also block them in our signal
mask. The signal mask is inherited by the child. Therefore, if the child
does not reset its mask (e.g. bash and most normal processes), it will
not receive any of the signals that we handle. So for example C-c
(SIGINT) does nothing in the child process.
We now unblock all signals before we exec the child.
It's also worth noting that if we _ignore_ a signal -
sigaction(SIG_IGN) - this is also inherited and we must reset it to
default. However, we do not ignore signals so this is unneeded.
Here is some more discussion on signalfd and this problem:
https://lwn.net/Articles/415684/
Signed-off-by: Ran Benita <ran234@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
log_warn is much shorter and we already use log_err instead of log_error
so this is more consistent now.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit adds a new pty object.
The pty object takes care of all pseudo terminal handling, reading and
writing. It can be opened and closed, and notify through callbacks when
input arrives or the child process exits/dies. It can also receive input
and pass it along to the child process.
There is not yet any real VTE processing, so we display raw escape
codes and so on. However, this should provide immediate feedback for
any further vte development, as we start to act like a real terminal
emulator.
Signed-off-by: Ran Benita <ran234@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>