[sanitizer] Intercept tcgetattr.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@185626 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/lit_tests/Linux/tcgetattr.cc b/lib/msan/lit_tests/Linux/tcgetattr.cc
new file mode 100644
index 0000000..e6e101d
--- /dev/null
+++ b/lib/msan/lit_tests/Linux/tcgetattr.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t %p
+
+#include <assert.h>
+#include <glob.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[]) {
+  int fd = getpt();
+  assert(fd >= 0);
+  
+  struct termios t;
+  int res = tcgetattr(fd, &t);
+  assert(!res);
+
+  if (t.c_iflag == 0)
+    exit(0);
+  return 0;
+}
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 762fe8e..5c7de75 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1495,7 +1495,6 @@
 #endif
 
 #if SANITIZER_INTERCEPT_MBSNRTOWCS
-
 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
             SIZE_T len, void *ps) {
   void *ctx;
@@ -1546,7 +1545,6 @@
 #endif
 
 #if SANITIZER_INTERCEPT_WCSNRTOMBS
-
 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
             SIZE_T len, void *ps) {
   void *ctx;
@@ -1566,6 +1564,22 @@
 #define INIT_WCSNRTOMBS
 #endif
 
+
+#if SANITIZER_INTERCEPT_TCGETATTR
+INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
+  int res = REAL(tcgetattr)(fd, termios_p);
+  if (!res && termios_p)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
+  return res;
+}
+
+#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr);
+#else
+#define INIT_TCGETATTR
+#endif
+
 #define SANITIZER_COMMON_INTERCEPTORS_INIT \
   INIT_STRCASECMP;                         \
   INIT_STRNCASECMP;                        \
@@ -1619,4 +1633,5 @@
   INIT_MBSTOWCS;                           \
   INIT_MBSNRTOWCS;                         \
   INIT_WCSTOMBS;                           \
-  INIT_WCSNRTOMBS;
+  INIT_WCSNRTOMBS;                         \
+  INIT_TCGETATTR;
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index fcdcd9b..a318f13 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -104,5 +104,6 @@
 # define SANITIZER_INTERCEPT_MBSNRTOWCS SI_MAC || SI_LINUX_NOT_ANDROID
 # define SANITIZER_INTERCEPT_WCSTOMBS SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_WCSNRTOMBS SI_MAC || SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index 76fee33..1ce60e7 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -348,6 +348,7 @@
   name[StatInt_wcstombs]                 = "  wcstombs                        ";
   name[StatInt_wcsrtombs]                = "  wcsrtombs                       ";
   name[StatInt_wcsnrtombs]               = "  wcsnrtombs                      ";
+  name[StatInt_tcgetattr]                = "  tcgetattr                       ";
 
   name[StatAnnotation]                   = "Dynamic annotations               ";
   name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index 10af377..e57ce8d 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -343,6 +343,7 @@
   StatInt_wcstombs,
   StatInt_wcsrtombs,
   StatInt_wcsnrtombs,
+  StatInt_tcgetattr,
 
   // Dynamic annotations.
   StatAnnotation,