From: Nikolaus Rath <Nikolaus@rath.org>
Date: Mon, 13 Nov 2017 12:31:56 +0000
Subject: Work around bug in mips+mipsel libc

Forwarded: no
Patch-Name: mips_dev_t.diff

On mips and mipsel, the st_dev and st_rdev members of struct stat do not
have type dev_t. This breaks POSIX compatibility, but is difficult to fix
(cf. https://sourceware.org/bugzilla/show_bug.cgi?id=17786).

To work around the issue, we change the definition of struct stat that
is used by Cython when we are compiling under mips. Note that this
requires the Cython compilation to run under mips, and that the
resulting C file will be mips specific (without the patch, the
generated C file is suitable for any architecture).

Upstream is not interested in this change for obvious reasons.
---
 Include/posix/__init__.py |  1 +
 Include/posix/stat.pxd    | 85 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)
 create mode 100644 Include/posix/__init__.py
 create mode 100644 Include/posix/stat.pxd

diff --git a/Include/posix/__init__.py b/Include/posix/__init__.py
new file mode 100644
index 0000000..ea30561
--- /dev/null
+++ b/Include/posix/__init__.py
@@ -0,0 +1 @@
+#empty
diff --git a/Include/posix/stat.pxd b/Include/posix/stat.pxd
new file mode 100644
index 0000000..a46f510
--- /dev/null
+++ b/Include/posix/stat.pxd
@@ -0,0 +1,85 @@
+from posix.types cimport (blkcnt_t, blksize_t, dev_t, gid_t, ino_t, mode_t,
+                          nlink_t, off_t, time_t, uid_t)
+
+IF UNAME_MACHINE in ('mips', 'mipsel'):
+    cdef extern from "<sys/stat.h>" nogil:
+        cdef struct struct_stat "stat":
+            unsigned st_dev
+            ino_t   st_ino
+            mode_t  st_mode
+            nlink_t st_nlink
+            uid_t   st_uid
+            gid_t   st_gid
+            unsigned st_rdev
+            off_t   st_size
+            blksize_t st_blksize
+            blkcnt_t st_blocks
+            time_t  st_atime
+            time_t  st_mtime
+            time_t  st_ctime
+            time_t  st_birthtime
+ELSE:
+    cdef extern from "<sys/stat.h>" nogil:
+        cdef struct struct_stat "stat":
+            dev_t   st_dev
+            ino_t   st_ino
+            mode_t  st_mode
+            nlink_t st_nlink
+            uid_t   st_uid
+            gid_t   st_gid
+            dev_t   st_rdev
+            off_t   st_size
+            blksize_t st_blksize
+            blkcnt_t st_blocks
+            time_t  st_atime
+            time_t  st_mtime
+            time_t  st_ctime
+            time_t  st_birthtime
+
+# POSIX prescribes including both <sys/stat.h> and <unistd.h> for these
+cdef extern from "<unistd.h>" nogil:
+    int fchmod(int, mode_t)
+    int chmod(const char *, mode_t)
+
+    int fstat(int, struct_stat *)
+    int lstat(const char *, struct_stat *)
+    int stat(const char *, struct_stat *)
+
+    # Macros for st_mode
+    mode_t S_ISREG(mode_t)
+    mode_t S_ISDIR(mode_t)
+    mode_t S_ISCHR(mode_t)
+    mode_t S_ISBLK(mode_t)
+    mode_t S_ISFIFO(mode_t)
+    mode_t S_ISLNK(mode_t)
+    mode_t S_ISSOCK(mode_t)
+
+    mode_t S_IFMT
+    mode_t S_IFREG
+    mode_t S_IFDIR
+    mode_t S_IFCHR
+    mode_t S_IFBLK
+    mode_t S_IFIFO
+    mode_t S_IFLNK
+    mode_t S_IFSOCK
+
+    # Permissions
+    mode_t S_ISUID
+    mode_t S_ISGID
+    mode_t S_ISVTX
+
+    mode_t S_IRWXU
+    mode_t S_IRUSR
+    mode_t S_IWUSR
+    mode_t S_IXUSR
+
+    mode_t S_IRWXG
+    mode_t S_IRGRP
+    mode_t S_IWGRP
+    mode_t S_IXGRP
+
+    mode_t S_IRWXO
+    mode_t S_IROTH
+    mode_t S_IWOTH
+    mode_t S_IXOTH
+            
