unix: Fix Termios type definition

- types_linux.go: Use the kernel-defined termios structure, *not* the
  LIBC-defined one. The LIBC termios structure cannot be safely used
  to do tty-related ioctls on all architectures (e.g. ppc64,
  ppc64le). The kernel termios structure, and the associated
  macros/constants, are defined in: "asm/termbits.h" which is included
  by "linux/termios.h". The LIBC termios structure is defined in
  "bits/termios.h" which is included by "termios.h". These structures
  are *not* the same.

  For systems that have both "struct termios" and "struct termios2"
  use the latter to define the Termios type. This is ok, since the
  "struct termios2" memory layout is compatible with "struct termios"
  (with a couple of fields added at the end). This way, type Termios
  can be used with both: the "old-style" TCSETS[FW], TCGETS ioctls,
  *and* with the new TCSETS[FW]2, TCGETS2 ioctls. The new ioctls allow
  configuring arbitrary baudrates.

  The new Termios definitions (kernel-compatible) have the same fields
  as the old ones (LIBC-derived) so there should be no user-code
  compatibility issues.

Change-Id: I3c1484c60f45b28e13404765c01616c33063afd5
Reviewed-on: https://go-review.googlesource.com/17185
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/unix/types_linux.go b/unix/types_linux.go
index 9b75633..d527587 100644
--- a/unix/types_linux.go
+++ b/unix/types_linux.go
@@ -50,12 +50,19 @@
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/icmpv6.h>
-#include <termios.h>
+#include <asm/termbits.h>
 #include <time.h>
 #include <unistd.h>
 #include <ustat.h>
 #include <utime.h>
 
+#ifdef TCSETS2
+// On systems that have "struct termios2" use this as type Termios.
+typedef struct termios2 termios_t;
+#else
+typedef struct termios termios_t;
+#endif
+
 enum {
 	sizeofPtr = sizeof(void*),
 };
@@ -396,4 +403,4 @@
 
 // Terminal handling
 
-type Termios C.struct_termios
+type Termios C.termios_t
diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go
index 9a58381..cf5db0e 100644
--- a/unix/ztypes_linux_386.go
+++ b/unix/ztypes_linux_386.go
@@ -1,8 +1,7 @@
+// +build 386,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
-// +build 386,linux
-
 package unix
 
 const (
@@ -580,13 +579,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Line   uint8
+	Cc     [19]uint8
+	Ispeed uint32
+	Ospeed uint32
 }
diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go
index f1937a6..ac27784 100644
--- a/unix/ztypes_linux_amd64.go
+++ b/unix/ztypes_linux_amd64.go
@@ -1,8 +1,7 @@
+// +build amd64,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
-// +build amd64,linux
-
 package unix
 
 const (
@@ -598,13 +597,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Line   uint8
+	Cc     [19]uint8
+	Ispeed uint32
+	Ospeed uint32
 }
diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go
index c8a0de4..b318bb8 100644
--- a/unix/ztypes_linux_arm.go
+++ b/unix/ztypes_linux_arm.go
@@ -1,8 +1,7 @@
+// +build arm,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
-// +build arm,linux
-
 package unix
 
 const (
@@ -569,115 +568,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Line   uint8
+	Cc     [19]uint8
+	Ispeed uint32
+	Ospeed uint32
 }
-
-const (
-	VINTR    = 0x0
-	VQUIT    = 0x1
-	VERASE   = 0x2
-	VKILL    = 0x3
-	VEOF     = 0x4
-	VTIME    = 0x5
-	VMIN     = 0x6
-	VSWTC    = 0x7
-	VSTART   = 0x8
-	VSTOP    = 0x9
-	VSUSP    = 0xa
-	VEOL     = 0xb
-	VREPRINT = 0xc
-	VDISCARD = 0xd
-	VWERASE  = 0xe
-	VLNEXT   = 0xf
-	VEOL2    = 0x10
-	IGNBRK   = 0x1
-	BRKINT   = 0x2
-	IGNPAR   = 0x4
-	PARMRK   = 0x8
-	INPCK    = 0x10
-	ISTRIP   = 0x20
-	INLCR    = 0x40
-	IGNCR    = 0x80
-	ICRNL    = 0x100
-	IUCLC    = 0x200
-	IXON     = 0x400
-	IXANY    = 0x800
-	IXOFF    = 0x1000
-	IMAXBEL  = 0x2000
-	IUTF8    = 0x4000
-	OPOST    = 0x1
-	OLCUC    = 0x2
-	ONLCR    = 0x4
-	OCRNL    = 0x8
-	ONOCR    = 0x10
-	ONLRET   = 0x20
-	OFILL    = 0x40
-	OFDEL    = 0x80
-	B0       = 0x0
-	B50      = 0x1
-	B75      = 0x2
-	B110     = 0x3
-	B134     = 0x4
-	B150     = 0x5
-	B200     = 0x6
-	B300     = 0x7
-	B600     = 0x8
-	B1200    = 0x9
-	B1800    = 0xa
-	B2400    = 0xb
-	B4800    = 0xc
-	B9600    = 0xd
-	B19200   = 0xe
-	B38400   = 0xf
-	CSIZE    = 0x30
-	CS5      = 0x0
-	CS6      = 0x10
-	CS7      = 0x20
-	CS8      = 0x30
-	CSTOPB   = 0x40
-	CREAD    = 0x80
-	PARENB   = 0x100
-	PARODD   = 0x200
-	HUPCL    = 0x400
-	CLOCAL   = 0x800
-	B57600   = 0x1001
-	B115200  = 0x1002
-	B230400  = 0x1003
-	B460800  = 0x1004
-	B500000  = 0x1005
-	B576000  = 0x1006
-	B921600  = 0x1007
-	B1000000 = 0x1008
-	B1152000 = 0x1009
-	B1500000 = 0x100a
-	B2000000 = 0x100b
-	B2500000 = 0x100c
-	B3000000 = 0x100d
-	B3500000 = 0x100e
-	B4000000 = 0x100f
-	ISIG     = 0x1
-	ICANON   = 0x2
-	XCASE    = 0x4
-	ECHO     = 0x8
-	ECHOE    = 0x10
-	ECHOK    = 0x20
-	ECHONL   = 0x40
-	NOFLSH   = 0x80
-	TOSTOP   = 0x100
-	ECHOCTL  = 0x200
-	ECHOPRT  = 0x400
-	ECHOKE   = 0x800
-	FLUSHO   = 0x1000
-	PENDIN   = 0x4000
-	IEXTEN   = 0x8000
-	TCGETS   = 0x5401
-	TCSETS   = 0x5402
-)
diff --git a/unix/ztypes_linux_arm64.go b/unix/ztypes_linux_arm64.go
index f989a36..a159aad 100644
--- a/unix/ztypes_linux_arm64.go
+++ b/unix/ztypes_linux_arm64.go
@@ -1,8 +1,7 @@
+// +build arm64,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs -- -fsigned-char types_linux.go
 
-// +build arm64,linux
-
 package unix
 
 const (
@@ -585,13 +584,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Line   uint8
+	Cc     [19]uint8
+	Ispeed uint32
+	Ospeed uint32
 }
diff --git a/unix/ztypes_linux_ppc64.go b/unix/ztypes_linux_ppc64.go
index 808203d..b14cbfe 100644
--- a/unix/ztypes_linux_ppc64.go
+++ b/unix/ztypes_linux_ppc64.go
@@ -1,8 +1,7 @@
+// +build ppc64,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
-// +build ppc64,linux
-
 package unix
 
 const (
@@ -595,13 +594,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [19]uint8
+	Line   uint8
+	Ispeed uint32
+	Ospeed uint32
 }
diff --git a/unix/ztypes_linux_ppc64le.go b/unix/ztypes_linux_ppc64le.go
index d4a689f..22c96a2 100644
--- a/unix/ztypes_linux_ppc64le.go
+++ b/unix/ztypes_linux_ppc64le.go
@@ -1,8 +1,7 @@
+// +build ppc64le,linux
 // Created by cgo -godefs - DO NOT EDIT
 // cgo -godefs types_linux.go
 
-// +build ppc64le,linux
-
 package unix
 
 const (
@@ -595,13 +594,12 @@
 )
 
 type Termios struct {
-	Iflag     uint32
-	Oflag     uint32
-	Cflag     uint32
-	Lflag     uint32
-	Line      uint8
-	Cc        [32]uint8
-	Pad_cgo_0 [3]byte
-	Ispeed    uint32
-	Ospeed    uint32
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [19]uint8
+	Line   uint8
+	Ispeed uint32
+	Ospeed uint32
 }