libadb-android icon indicating copy to clipboard operation
libadb-android copied to clipboard

shell:<command> is not non-interactive in true sense

Open mirfatif opened this issue 1 year ago • 2 comments

With shell: service it's not possible to use raw (non-interactive) mode. adbd still attaches the forked process of the sent command to a pseudo terminal device, but some interactive flags are removed using cfmakeraw.

So we cannot use tty, isatty etc. reliably. But we can check, say IGNBRK for STDIN and OPOST for STDOUT/STDERR, as these flags have been removed.

Native code, compiled and copied to /data/local/tmp/:

// is_a_tty

#include <termios.h>
#include <sys/ioctl.h>
#include <android/log.h>

int main(void)
{
  struct termios term;

  for (int fd = 0; fd < 3; fd++)
  {
    if (ioctl(fd, TCGETS, &term) < 0)
      __android_log_print(ANDROID_LOG_INFO, "is_a_tty", "%d is not a terminal", fd);
    else if (fd == 0)
      __android_log_print(ANDROID_LOG_INFO, "is_a_tty", "%d is a terminal, IGNBRK supported: %s", fd, term.c_iflag & IGNBRK ? "true" : "false");
    else
      __android_log_print(ANDROID_LOG_INFO, "is_a_tty", "%d is a terminal, OPOST supported: %s", fd, term.c_oflag & OPOST ? "true" : "false");
  }
}

Java code:

class AdbConnManager : AbsAdbConnectionManager() {
  ...
}
  
AdbConnManager().use {
  it.connect(5555)
  it.openStream("shell:/data/local/tmp/is_a_tty")
}

When we run it, it says:

is_a_tty: 0 is a terminal, IGNBRK supported: false
is_a_tty: 1 is a terminal, OPOST supported: false
is_a_tty: 2 is a terminal, OPOST supported: false

Expected behavior is that standard FDs should fail with ENOTTY as is the case with non-interactive adb shell:

~$ adb shell /data/local/tmp/is_a_tty
~$ adb logcat -d -s is_a_tty
is_a_tty: 0 is not a terminal
is_a_tty: 1 is not a terminal
is_a_tty: 2 is not a terminal

It's because adb shell uses shell protocol for communication with adbd. So in our case, running like openStream("shell,v2,raw:/data/local/tmp/is_a_tty") works i.e. standard FDs are no more attached to a PTY. But here comes the next problem: reading and writing to AdbStream no more works because libadb-android does not support shell protocol (version 2) (related feature request).

PS: I've created this issue for future reference. Close it if you want.

mirfatif avatar Dec 23 '23 17:12 mirfatif

As a side note, tcpip:<port> also works. You can add it to SERVICES.md.

mirfatif avatar Dec 23 '23 17:12 mirfatif

The library still has lots of issues and reflects its predecessors rather than the AOSP (for the sake of familiarity). But some of these has to change, eventually.

MuntashirAkon avatar Dec 30 '23 06:12 MuntashirAkon