@@ -48,7 +48,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
bits/termios-c_iflag.h bits/termios-c_oflag.h \
bits/termios-baud.h bits/termios-c_cflag.h \
bits/termios-c_lflag.h bits/termios-tcflow.h \
- bits/termios-misc.h
+ bits/termios-misc.h \
+ bits/ipc-perm.h
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
deleted file mode 100644
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
- unsigned int mode; /* Read/write permission. */
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad1;
- __syscall_ulong_t __glibc_reserved1;
- __syscall_ulong_t __glibc_reserved2;
- };
deleted file mode 100644
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- unsigned int uid; /* Owner's user ID. */
- unsigned int gid; /* Owner's group ID. */
- unsigned int cuid; /* Creator's user ID. */
- unsigned int cgid; /* Creator's group ID. */
- unsigned int mode; /* Read/write permission. */
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad1;
- unsigned long int __glibc_reserved1;
- unsigned long int __glibc_reserved2;
- };
@@ -128,6 +128,9 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
+GLIBC_2.30 msgctl F
+GLIBC_2.30 semctl F
+GLIBC_2.30 shmctl F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _Exit F
@@ -17,6 +17,7 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
+#include <endian.h>
#include_next <kernel-features.h>
/* The ARM kernel before 3.14.3 may or may not support
@@ -51,3 +52,6 @@
#define __ASSUME_CLONE_BACKWARDS 1
#undef __ASSUME_SYSVIPC_DEFAULT_IPC_64
+#if __BYTE_ORDER == __BIG_ENDIAN
+# undef __ASSUME_SYSVIPC_SUPPORT_MODE32
+#endif
new file mode 100644
@@ -0,0 +1,40 @@
+/* struct ipc_perm definition.
+ Copyright (C) 2019 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
+#endif
+
+/* Data structure used to pass permission information to IPC operations.
+ It follows the kernel ipc64_perm size so the syscall can be made directly
+ without temporary buffer copy. However, since glibc defines the MODE
+ field as mode_t per POSIX definition (BZ#18231), it omits the __PAD1 field
+ (since glibc does not export mode_t as 16-bit for any architecture). */
+struct ipc_perm
+{
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ __mode_t mode; /* Read/write permission. */
+ unsigned short int __seq; /* Sequence number. */
+ unsigned short int __pad2;
+ __syscall_ulong_t __glibc_reserved1;
+ __syscall_ulong_t __glibc_reserved2;
+};
@@ -37,19 +37,4 @@
/* Special key values. */
#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
- unsigned short int mode; /* Read/write permission. */
- unsigned short int __pad1;
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad2;
- __syscall_ulong_t __glibc_reserved1;
- __syscall_ulong_t __glibc_reserved2;
- };
+#include <bits/ipc-perm.h>
new file mode 100644
@@ -0,0 +1,37 @@
+/* struct ipc_perm definition.
+ Copyright (C) 2019 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_IPC_H
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
+#endif
+
+/* Data structure used to pass permission information to IPC operations. */
+struct ipc_perm
+ {
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ __mode_t mode; /* Read/write permission. */
+ unsigned short int __pad2;
+ unsigned short int __seq; /* Sequence number. */
+ unsigned int __pad3;
+ __extension__ unsigned long long int __glibc_reserved1;
+ __extension__ unsigned long long int __glibc_reserved2;
+ };
deleted file mode 100644
@@ -1,62 +0,0 @@
-/* Copyright (C) 1995-2019 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
-#if __WORDSIZE == 32
- unsigned short int __pad1;
- unsigned short int mode; /* Read/write permission. */
- unsigned short int __pad2;
-#else
- __mode_t mode; /* Read/write permission. */
- unsigned short int __pad2;
-#endif
- unsigned short int __seq; /* Sequence number. */
- unsigned int __pad3;
- __extension__ unsigned long long int __glibc_reserved1;
- __extension__ unsigned long long int __glibc_reserved2;
- };
deleted file mode 100644
@@ -1,53 +0,0 @@
-/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
-
- 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <sys/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#define IPC_INFO 3 /* See ipcs. */
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
- __mode_t mode; /* Read/write permission. */
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad1;
- unsigned long int __glibc_reserved1;
- unsigned long int __glibc_reserved2;
- };
@@ -83,6 +83,15 @@
/* The generic default __IPC_64 value is 0x0, however some architectures
require a different value of 0x100. */
#define __ASSUME_SYSVIPC_DEFAULT_IPC_64 1
+/* Assume that ipc_perm MODE kernel ABI has a 32-bit size or it is has padding
+ on the correct place (so if userland defines it as 32-bit, large values
+ will use the padding).
+ All supported architectures reserve 32-bit MODE space with extra padding.
+ However, some kernel ABI interfaces still expected a 16-bit field. This
+ is only an issue is arch-defined IPC_PERM padding is on a wrong position
+ regarding endianness. For this case, the IPC control routines (msgctl,
+ semctl, and semctl) requires to shift the value for the correct place. */
+#define __ASSUME_SYSVIPC_SUPPORT_MODE32 1
/* Support for p{read,write}v2 was added in 4.6. However Linux default
implementation does not assume the __ASSUME_* and instead use a fallback
@@ -2135,5 +2135,8 @@ GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
+GLIBC_2.30 msgctl F
+GLIBC_2.30 semctl F
+GLIBC_2.30 shmctl F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
@@ -15,6 +15,7 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
+#include <endian.h>
/* All supported kernel versions for MicroBlaze have these syscalls. */
#define __ASSUME_SOCKET_SYSCALL 1
@@ -69,3 +70,6 @@
#define __ASSUME_CLONE_BACKWARDS3
#undef __ASSUME_SYSVIPC_DEFAULT_IPC_64
+#if __BYTE_ORDER == __BIG_ENDIAN
+# undef __ASSUME_SYSVIPC_SUPPORT_MODE32
+#endif
deleted file mode 100644
@@ -1,54 +0,0 @@
-/* Copyright (C) 1995-2019 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- unsigned int uid; /* Owner's user ID. */
- unsigned int gid; /* Owner's group ID. */
- unsigned int cuid; /* Creator's user ID. */
- unsigned int cgid; /* Creator's group ID. */
- unsigned int mode; /* Read/write permission. */
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad1;
- unsigned long int __glibc_reserved1;
- unsigned long int __glibc_reserved2;
-};
@@ -23,11 +23,15 @@
#include <errno.h>
#ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32
+# define DEFAULT_VERSION GLIBC_2_2
+# else
+# define DEFAULT_VERSION GLIBC_2_30
+# endif
#endif
-int
-__new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
+static int
+msgctl_syscall (int msqid, int cmd, struct msqid_ds *buf)
{
#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf);
@@ -36,8 +40,54 @@ __new_msgctl (int msqid, int cmd, struct msqid_ds *buf)
buf);
#endif
}
+
+int
+__new_msgctl (int msqid, int cmd, struct msqid_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)");
+
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ struct msqid_ds tmpds;
+ if (cmd == IPC_SET)
+ {
+ tmpds = *buf;
+ tmpds.msg_perm.mode *= 0x10000U;
+ buf = &tmpds;
+ }
+#endif
+
+ int ret = msgctl_syscall (msqid, cmd, buf);
+
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ if (ret >= 0)
+ {
+ switch (cmd)
+ {
+ case IPC_STAT:
+ case MSG_STAT:
+ case MSG_STAT_ANY:
+ buf->msg_perm.mode >>= 16;
+ }
+ }
+#endif
+
+ return ret;
+}
versioned_symbol (libc, __new_msgctl, msgctl, DEFAULT_VERSION);
+#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \
+ && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30)
+int
+attribute_compat_text_section
+__msgctl_mode16 (int msqid, int cmd, struct msqid_ds *buf)
+{
+ return msgctl_syscall (msqid, cmd, buf);
+}
+compat_symbol (libc, __msgctl_mode16, msgctl, GLIBC_2_2);
+#endif
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
struct __old_msqid_ds
similarity index 62%
rename from sysdeps/unix/sysv/linux/powerpc/bits/ipc.h
rename to sysdeps/unix/sysv/linux/powerpc/bits/ipc-perm.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
+/* struct ipc_perm definition.
+ Copyright (C) 1995-2019 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
@@ -16,28 +17,9 @@
<http://www.gnu.org/licenses/>. */
#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
#endif
-#include <bits/types.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
/* Data structure used to pass permission information to IPC operations. */
struct ipc_perm
{
deleted file mode 100644
@@ -1,60 +0,0 @@
-/* Copyright (C) 2001-2019 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
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
-#endif
-
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-#define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
-/* Data structure used to pass permission information to IPC operations. */
-struct ipc_perm
- {
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
-#if __WORDSIZE == 64
- __mode_t mode; /* Read/write permission. */
-#else
- unsigned short int mode; /* Read/write permission. */
- unsigned short int __pad1;
-#endif
- unsigned short int __seq; /* Sequence number. */
- unsigned short int __pad2;
- unsigned long int __glibc_reserved1;
- unsigned long int __glibc_reserved2;
- };
@@ -50,6 +50,9 @@
# undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
# undef __ASSUME_SYSVIPC_DEFAULT_IPC_64
#endif
+#ifndef __s390x__
+# undef __ASSUME_SYSVIPC_SUPPORT_MODE32
+#endif
#undef __ASSUME_CLONE_DEFAULT
#define __ASSUME_CLONE_BACKWARDS2
@@ -2173,6 +2173,9 @@ GLIBC_2.30 __nldbl_warn F
GLIBC_2.30 __nldbl_warnx F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
+GLIBC_2.30 msgctl F
+GLIBC_2.30 semctl F
+GLIBC_2.30 shmctl F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 _IO_fprintf F
@@ -33,12 +33,33 @@ union semun
};
#ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32
+# define DEFAULT_VERSION GLIBC_2_2
+# else
+# define DEFAULT_VERSION GLIBC_2_30
+# endif
#endif
+static int
+semctl_syscall (int semid, int semnum, int cmd, union semun arg)
+{
+#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+ return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
+ arg.array);
+#else
+ return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
+ SEMCTL_ARG_ADDRESS (arg));
+#endif
+}
+
int
__new_semctl (int semid, int semnum, int cmd, ...)
{
+ /* POSIX states ipc_perm mode should have type of mode_t. */
+ _Static_assert (sizeof ((struct semid_ds){0}.sem_perm.mode)
+ == sizeof (mode_t),
+ "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
+
union semun arg = { 0 };
va_list ap;
@@ -59,16 +80,65 @@ __new_semctl (int semid, int semnum, int cmd, ...)
break;
}
-#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
- return INLINE_SYSCALL_CALL (semctl, semid, semnum, cmd | __IPC_64,
- arg.array);
-#else
- return INLINE_SYSCALL_CALL (ipc, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
- SEMCTL_ARG_ADDRESS (arg));
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ struct semid_ds tmpds;
+ if (cmd == IPC_SET)
+ {
+ tmpds = *arg.buf;
+ tmpds.sem_perm.mode *= 0x10000U;
+ arg.buf = &tmpds;
+ }
+#endif
+
+ int ret = semctl_syscall (semid, semnum, cmd, arg);
+
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ if (ret >= 0)
+ {
+ switch (cmd)
+ {
+ case IPC_STAT:
+ case SEM_STAT:
+ case SEM_STAT_ANY:
+ arg.buf->sem_perm.mode >>= 16;
+ }
+ }
#endif
+
+ return ret;
}
versioned_symbol (libc, __new_semctl, semctl, DEFAULT_VERSION);
+#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \
+ && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30)
+int
+attribute_compat_text_section
+__semctl_mode16 (int semid, int semnum, int cmd, ...)
+{
+ union semun arg = { 0 };
+ va_list ap;
+
+ /* Get the argument only if required. */
+ switch (cmd)
+ {
+ case SETVAL: /* arg.val */
+ case GETALL: /* arg.array */
+ case SETALL:
+ case IPC_STAT: /* arg.buf */
+ case IPC_SET:
+ case SEM_STAT:
+ case IPC_INFO: /* arg.__buf */
+ case SEM_INFO:
+ va_start (ap, cmd);
+ arg = va_arg (ap, union semun);
+ va_end (ap);
+ break;
+ }
+
+ return semctl_syscall (semid, semnum, cmd, arg);
+}
+compat_symbol (libc, __semctl_mode16, semctl, GLIBC_2_2);
+#endif
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
/* Since semctl use a variadic argument for semid_ds there is not need to
@@ -2043,6 +2043,9 @@ GLIBC_2.3.4 xdr_quad_t F
GLIBC_2.3.4 xdr_u_quad_t F
GLIBC_2.30 getdents64 F
GLIBC_2.30 gettid F
+GLIBC_2.30 msgctl F
+GLIBC_2.30 semctl F
+GLIBC_2.30 shmctl F
GLIBC_2.30 tgkill F
GLIBC_2.30 twalk_r F
GLIBC_2.4 __confstr_chk F
@@ -20,6 +20,8 @@
#ifndef __KERNEL_FEATURES_SH__
# define __KERNEL_FEATURES_SH__
+#include <endian.h>
+
/* These syscalls were added for SH in 2.6.37. */
#define __ASSUME_SOCKET_SYSCALL 1
#define __ASSUME_BIND_SYSCALL 1
@@ -46,6 +48,9 @@
# undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
# undef __ASSUME_SYSVIPC_DEFAULT_IPC_64
#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+# undef __ASSUME_SYSVIPC_SUPPORT_MODE32
+#endif
/* Support for several syscalls was added in 4.8. */
#if __LINUX_KERNEL_VERSION < 0x040800
@@ -23,15 +23,16 @@
#include <shlib-compat.h>
#include <errno.h>
-
#ifndef DEFAULT_VERSION
-# define DEFAULT_VERSION GLIBC_2_2
+# ifdef __ASSUME_SYSVIPC_SUPPORT_MODE32
+# define DEFAULT_VERSION GLIBC_2_2
+# else
+# define DEFAULT_VERSION GLIBC_2_30
+# endif
#endif
-
-/* Provide operations to control over shared memory segments. */
-int
-__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+static int
+shmctl_syscall (int shmid, int cmd, struct shmid_ds *buf)
{
#ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf);
@@ -40,8 +41,55 @@ __new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
buf);
#endif
}
+
+/* Provide operations to control over shared memory segments. */
+int
+__new_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+ /* POSIX states ipc_perm mode should have type of mode_t. */
+ _Static_assert (sizeof ((struct shmid_ds){0}.shm_perm.mode)
+ == sizeof (mode_t),
+ "sizeof (msqid_ds.msg_perm.mode) != sizeof (mode_t)");
+
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ struct shmid_ds tmpds;
+ if (cmd == IPC_SET)
+ {
+ tmpds = *buf;
+ tmpds.shm_perm.mode *= 0x10000U;
+ buf = &tmpds;
+ }
+#endif
+
+ int ret = shmctl_syscall (shmid, cmd, buf);
+
+#ifndef __ASSUME_SYSVIPC_SUPPORT_MODE32
+ if (ret >= 0)
+ {
+ switch (cmd)
+ {
+ case IPC_STAT:
+ case SHM_STAT:
+ case SHM_STAT_ANY:
+ buf->shm_perm.mode >>= 16;
+ }
+ }
+#endif
+
+ return ret;
+}
versioned_symbol (libc, __new_shmctl, shmctl, DEFAULT_VERSION);
+#if !defined __ASSUME_SYSVIPC_SUPPORT_MODE32 \
+ && SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_30)
+int
+attribute_compat_text_section
+__shmctl_mode16 (int shmid, int cmd, struct shmid_ds *buf)
+{
+ return shmctl_syscall (shmid, cmd, buf);
+}
+compat_symbol (libc, __shmctl_mode16, shmctl, GLIBC_2_2);
+#endif
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
struct __old_shmid_ds
similarity index 59%
rename from sysdeps/unix/sysv/linux/sparc/bits/ipc.h
rename to sysdeps/unix/sysv/linux/sparc/bits/ipc-perm.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
+/* struct ipc_perm definition.
+ Copyright (C) 1995-2019 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
@@ -16,29 +17,9 @@
<http://www.gnu.org/licenses/>. */
#ifndef _SYS_IPC_H
-# error "Never use <bits/ipc.h> directly; include <sys/ipc.h> instead."
+# error "Never use <bits/ipc-perm.h> directly; include <sys/ipc.h> instead."
#endif
-#include <bits/types.h>
-#include <bits/wordsize.h>
-
-/* Mode bits for `msgget', `semget', and `shmget'. */
-#define IPC_CREAT 01000 /* Create key if key does not exist. */
-#define IPC_EXCL 02000 /* Fail if key exists. */
-#define IPC_NOWAIT 04000 /* Return error on wait. */
-
-/* Control commands for `msgctl', `semctl', and `shmctl'. */
-#define IPC_RMID 0 /* Remove identifier. */
-#define IPC_SET 1 /* Set `ipc_perm' options. */
-#define IPC_STAT 2 /* Get `ipc_perm' options. */
-#ifdef __USE_GNU
-# define IPC_INFO 3 /* See ipcs. */
-#endif
-
-/* Special key values. */
-#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
-
-
/* Data structure used to pass permission information to IPC operations. */
struct ipc_perm
{
@@ -47,14 +28,8 @@ struct ipc_perm
__gid_t gid; /* Owner's group ID. */
__uid_t cuid; /* Creator's user ID. */
__gid_t cgid; /* Creator's group ID. */
-#if __WORDSIZE == 32
- unsigned short int __pad1;
- unsigned short int mode; /* Read/write permission. */
- unsigned short int __pad2;
-#else
__mode_t mode; /* Read/write permission. */
unsigned short int __pad1;
-#endif
unsigned short int __seq; /* Sequence number. */
__extension__ unsigned long long int __glibc_reserved1;
__extension__ unsigned long long int __glibc_reserved2;