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

TCSANOW not defined correctly in unified headers #441

Closed
alexcohn opened this issue Jul 2, 2017 · 5 comments
Closed

TCSANOW not defined correctly in unified headers #441

alexcohn opened this issue Jul 2, 2017 · 5 comments
Assignees
Labels
Milestone

Comments

@alexcohn
Copy link

alexcohn commented Jul 2, 2017

Description

Both platforms/android-14/arch-arm/usr/include/termios.h and platforms/android-14/arch-x86/usr/include/termios.h redefine TCSANOW to TCSETS, which is 0x5402. But for uniform headers, it is only redefined for MIPS.

As a result, tcsetattr(fd, TCSANOW, &cfg) fails with EINVAL on ARM with APP_PLATFORM=android-14, see https://stackoverflow.com/questions/44870554/ndk-15-breaks-serial-port-library.

I believe this will not work even for android-21 and higher, where tcsetattr is part of libc, but I don't have a proof.

Environment Details

  • NDK Version: 15.1.4119039.
  • ABI: arm, x86
  • NDK API level: 14
@enh enh self-assigned this Jul 2, 2017
@enh
Copy link
Contributor

enh commented Jul 2, 2017

ugh.

when i wrote tcsetattr for the platform in L (21), i wrote this:

int tcsetattr(int fd, int optional_actions, const termios* s) {
  int cmd;
  switch (optional_actions) {
    case TCSANOW: cmd = TCSETS; break;
    case TCSADRAIN: cmd = TCSETSW; break;
    case TCSAFLUSH: cmd = TCSETSF; break;
    default: errno = EINVAL; return -1;
  }
  return ioctl(fd, cmd, s);
}

but apparently the NDK had this instead:

#undef  TCSANOW
#define TCSANOW    TCSETS

#undef  TCSADRAIN
#define TCSADRAIN  TCSETSW

#undef  TCSAFLUSH
#define TCSAFLUSH  TCSETSF

static __inline int tcsetattr(int fd, int __opt, const struct termios *s) {
  return ioctl(fd, __opt, (void *)s);
}

only half of which was been cleaned up when we added legacy_termios_inlines.h.

this bug gives me such deja vu that i'm sure i've been through legacy_termios_inlines.h at some point, but git log says otherwise. (there's a mysterious reference to "getting bogged down yesterday" in the code review for danalbert's latest change to that file, so i'm not completely mad, but it seems like i gave up for unknown reasons. there also doesn't seem to be an internal bug filed, so it looks like we just dropped the ball here.)

@fornwall
Copy link

fornwall commented Jul 5, 2017

So when targeting android-21 or later with unified headers, so that the inline versions in legacy_termios_inlines.h are skippped, tcsetattr(fd, TCSANOW, &cfg) will actually currently:

  1. Work on non-mips, since TCSANOW is not redefined and passed into the libc implementation given above which expects the original value (0).

  2. Not work on mips, since TCSANOW gets redefined which the libc function does not expect.

And when targeting earlier versions than android-21, the situation is reversed and only work on mips ?

@alexcohn
Copy link
Author

alexcohn commented Jul 5, 2017

@fornwall look likely, but I must confess that I never tried any of these in real life.

@enh
Copy link
Contributor

enh commented Jul 5, 2017

no, it'll work fine for all architectures [>=21] because the implementation is compiled against those headers, so the implementation will be looking for the implementation-specific value of TCSANOW, whatever that is.

@enh
Copy link
Contributor

enh commented Jul 5, 2017

proposed fix: https://android-review.googlesource.com/429041

it's a little bit ugly, which is probably where i ground to a halt last time, but having two different implementations is [demonstrably] worse.

@DanAlbert DanAlbert added this to the r16 milestone Jul 10, 2017
hubot pushed a commit to aosp-mirror/platform_bionic that referenced this issue Jul 10, 2017
Before this change we have the old NDK inline termios functions with the
modern constants. Unfortunately the old NDK inline functions relied on
hacking the constants. Fix things by sharing the implementation between
the platform and the NDK headers.

Bug: android/ndk#441
Test: ran tests
Change-Id: I2773634059530bc954167f29c4783413a2294d5a
@enh enh modified the milestones: r15c, r16 Jul 18, 2017
@enh enh added the headers label Jul 18, 2017
@enh enh assigned DanAlbert and unassigned enh Jul 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants