]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
sysv: linux: Add 64-bit time_t variant for msgctl
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 30 Jun 2020 12:20:48 +0000 (09:20 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 9 Jul 2020 15:05:40 +0000 (12:05 -0300)
To provide a y2038 safe interface a new symbol __msgctl64 is added
and __msgctl is change to call it instead (it adds some extra buffer
coping for the 32 bit time_t implementation).

Two new structures are added:

  1. kernel_msqid64_ds: used internally only on 32-bit architectures
     to issue the syscall.  A handful of architectures (hppa, i386, mips,
     powerpc32, and sparc32) require specific implementations due to
     their kernel ABI.

  2. msqid_ds64: this is only for __TIMESIZE != 64 to use along with
     the 64-bit msgctl.  It is different than the kernel struct because
     the exported 64-bit time_t might require different alignment
     depending on the architecture ABI.

So the resulting implementation does:

  1. For 64-bit architectures it assumes msqid_ds already contains
     64-bit time_t fields and will result in just the __msgctl symbol
     using the __msgctl64 code.  The msgid_ds argument is passed as-is
     to the syscall.

  2. For 32-bit architectures with default 64-bit time_t (newer ABIs
     such riscv32 or arc), it will also result in only one exported
     symbol but with the required high/low time handling.

  3. Finally for 32-bit architecture with both 32-bit and 64-bit time_t
     support we follow the already set way to provide one symbol with
     64-bit time_t support and implement the 32-bit time_t support using
     the 64-bit time_t.

     The default 32-bit symbol will allocate and copy the msqid_ds
     over multiple buffers, but this should be deprecated in favor
     of the __msgctl64 anyway.

Checked on i686-linux-gnu and x86_64-linux-gnu.  I also did some sniff
tests on powerpc, powerpc64, mips, mips64, armhf, sparcv9, and
sparc64.

Tested-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Tested-by: Alistair Francis <alistair.francis@wdc.com>
15 files changed:
include/sys/msg.h
sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/bits/types/struct_msqid_ds.h
sysdeps/unix/sysv/linux/hppa/bits/types/struct_msqid_ds.h
sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/include/sys/msg.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/bits/types/struct_msqid_ds.h
sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/msgctl.c
sysdeps/unix/sysv/linux/powerpc/bits/types/struct_msqid_ds.h
sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/sparc/bits/types/struct_msqid_ds.h
sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h [new file with mode: 0644]

index 43ec5b94729fde11d634057b8928d3040eadcaa5..a092d0e216ceeae4ad18d02edce6a0e9a90ebfc2 100644 (file)
@@ -1,11 +1 @@
-#ifndef _SYS_MSG_H
-#include <sysvipc/sys/msg.h>
-
-#ifndef _ISOMAC
-extern ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz,
-                             long int msgtyp, int msgflg);
-extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
-                         int msgflg);
-#endif
-
-#endif
+#include_next <sys/msg.h>
diff --git a/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h b/sysdeps/unix/sysv/linux/bits/types/struct_msqid64_ds.h
new file mode 100644 (file)
index 0000000..3536c8e
--- /dev/null
@@ -0,0 +1,38 @@
+/* Generic implementation of the SysV message struct msqid64_ds.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _SYS_MSG_H
+# error "Never use <bits/msq.h> directly; include <sys/msg.h> instead."
+#endif
+
+#if __TIMESIZE == 64
+# define __msqid64_ds msqid_ds
+#else
+struct __msqid64_ds
+{
+  struct ipc_perm msg_perm;    /* structure describing operation permission */
+  __time64_t msg_stime;                /* time of last msgsnd command */
+  __time64_t msg_rtime;                /* time of last msgsnd command */
+  __time64_t msg_ctime;                /* time of last change */
+  __syscall_ulong_t __msg_cbytes; /* current number of bytes on queue */
+  msgqnum_t msg_qnum;          /* number of messages currently on queue */
+  msglen_t msg_qbytes;         /* max number of bytes allowed on queue */
+  __pid_t msg_lspid;           /* pid of last msgsnd() */
+  __pid_t msg_lrpid;           /* pid of last msgrcv() */
+};
+#endif
index 32173a7b60092367d66d0f78a7c231cd9162d6cd..43b38175ad9949886d2bfd8f256fe683ab6305a2 100644 (file)
@@ -27,11 +27,11 @@ struct msqid_ds
   struct ipc_perm msg_perm;    /* structure describing operation permission */
 #if __TIMESIZE == 32
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_ctime;          /* time of last change */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
 #else
   __time_t msg_stime;          /* time of last msgsnd command */
   __time_t msg_rtime;          /* time of last msgsnd command */
index 3cf70e36c4dcb47a82e3dff6c4a274a87df91afc..16eac46941db47c9fe50c67363a20d6f4a1fba09 100644 (file)
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm;    /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime;          /* time of last change */
 #else
   __time_t msg_stime;          /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/hppa/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..69a63ee
--- /dev/null
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/i386/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..65b9405
--- /dev/null
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct compat_msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime;
+  unsigned long msg_stime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/include/sys/msg.h b/sysdeps/unix/sysv/linux/include/sys/msg.h
new file mode 100644 (file)
index 0000000..522903f
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _SYS_MSG_H
+#include <sysvipc/sys/msg.h>
+
+#ifndef _ISOMAC
+extern ssize_t __libc_msgrcv (int msqid, void *msgp, size_t msgsz,
+                             long int msgtyp, int msgflg);
+extern int __libc_msgsnd (int msqid, const void *msgp, size_t msgsz,
+                         int msgflg);
+
+# include <bits/types/struct_msqid64_ds.h>
+
+# if __TIMESIZE == 64
+#  define __msgctl64 __msgctl
+# else
+extern int __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf);
+libc_hidden_proto (__msgctl64);
+# endif
+
+#endif
+
+#endif
index e012db8b528afe3a22fda5250ca60cffd4111173..513e01a171449404c6547e0cbe891d73e904f869 100644 (file)
@@ -28,17 +28,17 @@ struct msqid_ds
 #if __TIMESIZE == 32
 # ifdef __MIPSEL__
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_ctime;          /* time of last change */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
 # else
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime;          /* time of last change */
 # endif
 #else
diff --git a/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/mips/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..9cfd5a0
--- /dev/null
@@ -0,0 +1,33 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+#if __TIMESIZE == 32
+# ifdef __MIPSEL__
+  unsigned long int msg_stime;
+  unsigned long int msg_stime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_ctime;
+  unsigned long int msg_ctime_high;
+# else
+  unsigned long int msg_stime_high;
+  unsigned long int msg_stime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_ctime_high;
+  unsigned long int msg_ctime;
+# endif
+#else
+  unsigned long int msg_stime;
+  unsigned long int msg_rtime;
+  unsigned long int msg_ctime;
+#endif
+  unsigned long int msg_cbytes;
+  unsigned long int msg_qnum;
+  unsigned long int msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long int __unused1;
+  unsigned long int __unused2;
+};
index fd46aec1a0172a342833c10667a1121a575a2a68..0776472d5e01dea3d4a90e5f025f5074e10d0250 100644 (file)
 #include <errno.h>
 #include <linux/posix_types.h>  /* For __kernel_mode_t.  */
 
-#ifndef DEFAULT_VERSION
-# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
-#  define DEFAULT_VERSION GLIBC_2_2
-# else
-#  define DEFAULT_VERSION GLIBC_2_31
-# endif
+/* POSIX states ipc_perm mode should have type of mode_t.  */
+_Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+               == sizeof (mode_t),
+               "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
+
+#if __IPC_TIME64 == 0
+typedef struct msqid_ds msgctl_arg_t;
+#else
+# include <struct_kernel_msqid64_ds.h>
+
+static void
+msqid64_to_kmsqid64 (const struct __msqid64_ds *msqid64,
+                    struct kernel_msqid64_ds *kmsqid)
+{
+  kmsqid->msg_perm       = msqid64->msg_perm;
+  kmsqid->msg_stime      = msqid64->msg_stime;
+  kmsqid->msg_stime_high = msqid64->msg_stime >> 32;
+  kmsqid->msg_rtime      = msqid64->msg_rtime;
+  kmsqid->msg_rtime_high = msqid64->msg_rtime >> 32;
+  kmsqid->msg_ctime      = msqid64->msg_ctime;
+  kmsqid->msg_ctime_high = msqid64->msg_ctime >> 32;
+  kmsqid->msg_cbytes     = msqid64->msg_cbytes;
+  kmsqid->msg_qnum       = msqid64->msg_qnum;
+  kmsqid->msg_qbytes     = msqid64->msg_qbytes;
+  kmsqid->msg_lspid      = msqid64->msg_lspid;
+  kmsqid->msg_lrpid      = msqid64->msg_lrpid;
+}
+
+static void
+kmsqid64_to_msqid64 (const struct kernel_msqid64_ds *kmsqid,
+                    struct __msqid64_ds *msqid64)
+{
+  msqid64->msg_perm   = kmsqid->msg_perm;
+  msqid64->msg_stime  = kmsqid->msg_stime
+                       | ((__time64_t) kmsqid->msg_stime_high << 32);
+  msqid64->msg_rtime  = kmsqid->msg_rtime
+                       | ((__time64_t) kmsqid->msg_rtime_high << 32);
+  msqid64->msg_ctime  = kmsqid->msg_ctime
+                       | ((__time64_t) kmsqid->msg_ctime_high << 32);
+  msqid64->msg_cbytes = kmsqid->msg_cbytes;
+  msqid64->msg_qnum   = kmsqid->msg_qnum;
+  msqid64->msg_qbytes = kmsqid->msg_qbytes;
+  msqid64->msg_lspid  = kmsqid->msg_lspid;
+  msqid64->msg_lrpid  = kmsqid->msg_lrpid;
+}
+
+typedef struct kernel_msqid64_ds msgctl_arg_t;
 #endif
 
 static int
-msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
+msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf)
 {
 #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
   return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf);
@@ -43,46 +84,119 @@ msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
 }
 
 int
-__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+__msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
 {
-  /* POSIX states ipc_perm mode should have type of mode_t.  */
-  _Static_assert (sizeof ((struct msqid_ds){0}.msg_perm.mode)
-                 == sizeof (mode_t),
-                 "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
-
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-  struct msqid_ds tmpds;
-  if (cmd == IPC_SET)
+#if __IPC_TIME64
+  struct kernel_msqid64_ds ksemid, *arg = NULL;
+  if (buf != NULL)
     {
-      tmpds = *buf;
-      tmpds.msg_perm.mode *= 0x10000U;
-      buf = &tmpds;
+      msqid64_to_kmsqid64 (buf, &ksemid);
+      arg = &ksemid;
     }
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+  if (cmd == IPC_SET)
+    arg->msg_perm.mode *= 0x10000U;
+# endif
+#else
+  msgctl_arg_t *arg = buf;
 #endif
 
-  int ret = msgctl_syscall (msqid, cmd, buf);
+  int ret = msgctl_syscall (msqid, cmd, arg);
+  if (ret < 0)
+    return ret;
 
-  if (ret >= 0)
+  switch (cmd)
     {
-      switch (cmd)
-       {
-       case IPC_STAT:
-       case MSG_STAT:
-       case MSG_STAT_ANY:
+    case IPC_STAT:
+    case MSG_STAT:
+    case MSG_STAT_ANY:
 #ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
-         buf->msg_perm.mode >>= 16;
+      arg->msg_perm.mode >>= 16;
 #else
-         /* Old Linux kernel versions might not clear the mode padding.  */
-         if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
-             != sizeof (__kernel_mode_t))
-           buf->msg_perm.mode &= 0xFFFF;
+      /* Old Linux kernel versions might not clear the mode padding.  */
+      if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
+          != sizeof (__kernel_mode_t))
+       arg->msg_perm.mode &= 0xFFFF;
+#endif
+
+#if __IPC_TIME64
+      kmsqid64_to_msqid64 (arg, buf);
 #endif
-       }
     }
 
   return ret;
 }
-versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION);
+#if __TIMESIZE != 64
+libc_hidden_def (__msgctl64)
+
+static void
+msqid_to_msqid64 (struct __msqid64_ds *mq64, const struct msqid_ds *mq)
+{
+  mq64->msg_perm   = mq->msg_perm;
+  mq64->msg_stime  = mq->msg_stime
+                    | ((__time64_t) mq->__msg_stime_high << 32);
+  mq64->msg_rtime  = mq->msg_rtime
+                    | ((__time64_t) mq->__msg_rtime_high << 32);
+  mq64->msg_ctime  = mq->msg_ctime
+                    | ((__time64_t) mq->__msg_ctime_high << 32);
+  mq64->msg_cbytes = mq->msg_cbytes;
+  mq64->msg_qnum   = mq->msg_qnum;
+  mq64->msg_qbytes = mq->msg_qbytes;
+  mq64->msg_lspid  = mq->msg_lspid;
+  mq64->msg_lrpid  = mq->msg_lrpid;
+}
+
+static void
+msqid64_to_msqid (struct msqid_ds *mq, const struct __msqid64_ds *mq64)
+{
+  mq->msg_perm         = mq64->msg_perm;
+  mq->msg_stime        = mq64->msg_stime;
+  mq->__msg_stime_high = 0;
+  mq->msg_rtime        = mq64->msg_rtime;
+  mq->__msg_rtime_high = 0;
+  mq->msg_ctime        = mq64->msg_ctime;
+  mq->__msg_ctime_high = 0;
+  mq->msg_cbytes       = mq64->msg_cbytes;
+  mq->msg_qnum         = mq64->msg_qnum;
+  mq->msg_qbytes       = mq64->msg_qbytes;
+  mq->msg_lspid        = mq64->msg_lspid;
+  mq->msg_lrpid        = mq64->msg_lrpid;
+}
+
+int
+__msgctl (int msqid, int cmd, struct msqid_ds *buf)
+{
+  struct __msqid64_ds msqid64, *buf64 = NULL;
+  if (buf != NULL)
+    {
+      msqid_to_msqid64 (&msqid64, buf);
+      buf64 = &msqid64;
+    }
+
+  int ret = __msgctl64 (msqid, cmd, buf64);
+  if (ret < 0)
+    return ret;
+
+  switch (cmd)
+    {
+    case IPC_STAT:
+    case MSG_STAT:
+    case MSG_STAT_ANY:
+      msqid64_to_msqid (buf, buf64);
+    }
+
+  return ret;
+}
+#endif
+
+#ifndef DEFAULT_VERSION
+# ifndef __ASSUME_SYSVIPC_BROKEN_MODE_T
+#  define DEFAULT_VERSION GLIBC_2_2
+# else
+#  define DEFAULT_VERSION GLIBC_2_31
+# endif
+#endif
+versioned_symbol (libc, __msgctl, msgctl, DEFAULT_VERSION);
 
 #if defined __ASSUME_SYSVIPC_BROKEN_MODE_T \
     && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_31)
@@ -90,7 +204,7 @@ int
 attribute_compat_text_section
 __msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf)
 {
-  return msgctl_syscall (msqid, cmd, buf);
+  return msgctl_syscall (msqid, cmd, (msgctl_arg_t *) buf);
 }
 compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2);
 #endif
index 4ae2fbcbdc9f5365d1e10a0692405692c2af3d8e..35cc51f733f136f5e7fde13091e68804532f01ac 100644 (file)
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm;    /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime;          /* time of last change */
 #else
   __time_t msg_stime;          /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..69a63ee
--- /dev/null
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
index 71980839c7944c59a14f74c7f534753ffebd26ed..502c23d91ee50ab1e100632b3375398bbd9d78a8 100644 (file)
@@ -26,11 +26,11 @@ struct msqid_ds
 {
   struct ipc_perm msg_perm;    /* structure describing operation permission */
 #if __TIMESIZE == 32
-  unsigned long int __glibc_reserved1;
+  unsigned long int __msg_stime_high;
   __time_t msg_stime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved2;
+  unsigned long int __msg_rtime_high;
   __time_t msg_rtime;          /* time of last msgsnd command */
-  unsigned long int __glibc_reserved3;
+  unsigned long int __msg_ctime_high;
   __time_t msg_ctime;          /* time of last change */
 #else
   __time_t msg_stime;          /* time of last msgsnd command */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/sparc/sparc32/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..69a63ee
--- /dev/null
@@ -0,0 +1,18 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long msg_stime_high;
+  unsigned long msg_stime;
+  unsigned long msg_rtime_high;
+  unsigned long msg_rtime;
+  unsigned long msg_ctime_high;
+  unsigned long msg_ctime;
+  unsigned long msg_cbytes;
+  unsigned long msg_qnum;
+  unsigned long msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long __unused1;
+  unsigned long __unused2;
+};
diff --git a/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h b/sysdeps/unix/sysv/linux/struct_kernel_msqid64_ds.h
new file mode 100644 (file)
index 0000000..b88d910
--- /dev/null
@@ -0,0 +1,19 @@
+/* Analogous to kernel struct msqid64_ds used on msgctl.  It is only used
+   for 32-bit architectures on 64-bit time_t msgctl64 implementation.  */
+struct kernel_msqid64_ds
+{
+  struct ipc_perm msg_perm;
+  unsigned long int msg_stime;
+  unsigned long int msg_stime_high;
+  unsigned long int msg_rtime;
+  unsigned long int msg_rtime_high;
+  unsigned long int msg_ctime;
+  unsigned long int msg_ctime_high;
+  unsigned long int msg_cbytes;
+  unsigned long int msg_qnum;
+  unsigned long int msg_qbytes;
+  __pid_t msg_lspid;
+  __pid_t msg_lrpid;
+  unsigned long int __unused4;
+  unsigned long int __unused5;
+};