Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mirfatif opened this issue Dec 23, 2023 · 2 comments
Open

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

mirfatif opened this issue Dec 23, 2023 · 2 comments

Comments

@mirfatif
Copy link
Contributor

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
Copy link
Contributor Author

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

@MuntashirAkon
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants