[parisc-linux-cvs] 2.4.14-pa10 sysv ipc cleanup
Thomas Bogendoerfer
tsbogend@alpha.franken.de
Fri, 23 Nov 2001 23:01:45 +0100
Hi,
I've checked in the sysv ipc cleanup, which I've been working on for the
last few days. I've added a compat mode for shmctl, which should make
it working better than before; msgctl and semctl are broken as before,
but it would be possible to fix them up, too. But I'd prefer to get rid
of that as soon as a new glibc, which uses the reworked syscalls, is
accepted. I'm going to put up the glibc patch, which I've used to
build the "new" glibc soon.
Thomas.
Index: arch/parisc/kernel/sys_parisc.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/sys_parisc.c,v
retrieving revision 1.13
diff -u -r1.13 sys_parisc.c
--- arch/parisc/kernel/sys_parisc.c 2001/07/14 04:08:23 1.13
+++ arch/parisc/kernel/sys_parisc.c 2001/11/23 00:25:33
@@ -152,3 +152,107 @@
return r;
return raddr;
}
+
+
+/*
+ * FIXME, please remove this crap as soon as possible
+ *
+ * This is here to fix up broken glibc structures,
+ * which are already fixed in newer glibcs
+ */
+#include <linux/msg.h>
+#include <linux/sem.h>
+#include <linux/shm.h>
+#include "sys32.h"
+
+struct broken_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;
+ unsigned long int __unused1;
+ unsigned long int __unused2;
+};
+
+struct broken_shmid64_ds {
+ struct broken_ipc_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+#ifndef __LP64__
+ unsigned int __pad1;
+#endif
+ __kernel_time_t shm_atime; /* last attach time */
+#ifndef __LP64__
+ unsigned int __pad2;
+#endif
+ __kernel_time_t shm_dtime; /* last detach time */
+#ifndef __LP64__
+ unsigned int __pad3;
+#endif
+ __kernel_time_t shm_ctime; /* last change time */
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned int shm_nattch; /* no. of current attaches */
+ unsigned int __unused1;
+ unsigned int __unused2;
+};
+
+static void convert_broken_perm (struct broken_ipc_perm *out, struct ipc64_perm *in)
+{
+ out->key = in->key;
+ out->uid = in->uid;
+ out->gid = in->gid;
+ out->cuid = in->cuid;
+ out->cgid = in->cgid;
+ out->mode = in->mode;
+ out->seq = in->seq;
+}
+
+static int copyout_broken_shmid64(struct broken_shmid64_ds *buf, struct shmid64_ds *sbuf)
+{
+ struct broken_shmid64_ds tbuf;
+
+ memset(&tbuf, 0, sizeof tbuf);
+ convert_broken_perm (&tbuf.shm_perm, &sbuf->shm_perm);
+ tbuf.shm_segsz = sbuf->shm_segsz;
+ tbuf.shm_atime = sbuf->shm_atime;
+ tbuf.shm_dtime = sbuf->shm_dtime;
+ tbuf.shm_ctime = sbuf->shm_ctime;
+ tbuf.shm_cpid = sbuf->shm_cpid;
+ tbuf.shm_lpid = sbuf->shm_lpid;
+ tbuf.shm_nattch = sbuf->shm_nattch;
+ return copy_to_user(buf, &tbuf, sizeof tbuf);
+}
+
+int sys_msgctl_broken(int msqid, int cmd, struct msqid_ds *buf)
+{
+ return sys_msgctl (msqid, cmd & ~IPC_64, buf);
+}
+
+int sys_semctl_broken(int semid, int semnum, int cmd, union semun arg)
+{
+ return sys_semctl (semid, semnum, cmd & ~IPC_64, arg);
+}
+
+int sys_shmctl_broken(int shmid, int cmd, struct shmid64_ds *buf)
+{
+ struct shmid64_ds sbuf;
+ int err;
+
+ if (cmd & IPC_64) {
+ cmd &= ~IPC_64;
+ if (cmd == IPC_STAT || cmd == SHM_STAT) {
+ KERNEL_SYSCALL(err, sys_shmctl, shmid, cmd, (struct shmid_ds *)&sbuf);
+ if (err == 0)
+ err = copyout_broken_shmid64((struct broken_shmid64_ds *)buf, &sbuf);
+ return err;
+ }
+ }
+ return sys_shmctl (shmid, cmd, (struct shmid_ds *)buf);
+}
+
Index: arch/parisc/kernel/sys_parisc32.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/sys_parisc32.c,v
retrieving revision 1.23
diff -u -r1.23 sys_parisc32.c
--- arch/parisc/kernel/sys_parisc32.c 2001/07/14 21:17:02 1.23
+++ arch/parisc/kernel/sys_parisc32.c 2001/11/23 21:46:01
@@ -2681,191 +2681,6 @@
return err;
}
-/* XXX FIXME Probably the msgctl() is not required */
-extern int ipc_parse_version (int *cmd);
-
-asmlinkage long sys32_msgctl (int msqid, int cmd, void *buf)
-{
- int err = -EINVAL;
-
- switch (cmd &~ IPC_64) {
-
- case IPC_INFO:
- case MSG_INFO:
- /* struct msginfo needs no translation -- fall through */
- case IPC_RMID:
- err = sys_msgctl (msqid, cmd, buf);
- break;
-
- case IPC_SET:
- /* Don't support the older stuff */
- if (ipc_parse_version(&cmd) != IPC_64) {
- printk(KERN_WARNING "msgctl() does not support libc5 IPC_SET\n");
- return -ENOSYS;
- }
- /* padded values (time_t's) aren't used, so this is safe */
- err = sys_msgctl(msqid, cmd, buf);
- break;
-
- case IPC_STAT:
- case MSG_STAT:
- /* Don't support the older stuff */
- if (ipc_parse_version(&cmd) != IPC_64) {
- printk(KERN_WARNING "msgctl() does not support libc5 IPC_STAT\n");
- return -ENOSYS;
- }
- err = sys_msgctl(msqid, cmd, buf);
- break;
-
- }
-
- return err;
-}
-
-struct shmid64_ds32 {
- struct ipc64_perm shm_perm; /* operation perms */
- unsigned int __pad1;
- __kernel_time_t32 shm_atime; /* last attach time */
- unsigned int __pad2;
- __kernel_time_t32 shm_dtime; /* last detach time */
- unsigned int __pad3;
- __kernel_time_t32 shm_ctime; /* last change time */
- __kernel_size_t32 shm_segsz; /* size of segment (bytes) */
- __kernel_pid_t shm_cpid; /* pid of creator */
- __kernel_pid_t shm_lpid; /* pid of last operator */
- unsigned int shm_nattch; /* no. of current attaches */
- unsigned int __unused1;
- unsigned int __unused2;
-};
-
-static int copyout_shmid64_ds32(struct shmid64_ds32 *buf, struct shmid64_ds *s64)
-{
- struct shmid64_ds32 s32;
- memcpy(&s32.shm_perm, &s64->shm_perm, sizeof s32.shm_perm);
- s32.shm_segsz = s64->shm_segsz;
- s32.shm_atime = s64->shm_atime;
- s32.shm_dtime = s64->shm_dtime;
- s32.shm_ctime = s64->shm_ctime;
- s32.shm_cpid = s64->shm_cpid;
- s32.shm_lpid = s64->shm_lpid;
- s32.shm_nattch = s64->shm_nattch;
- return copy_to_user(buf, &s32, sizeof s32);
-}
-
-asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg)
-{
- int err = -EINVAL;
- struct shmid64_ds s64;
- union semun u;
- int version = ipc_parse_version(&cmd);
-
- switch (cmd) {
- case SETVAL:
- /* Ugh. arg is a union of int,ptr,ptr,ptr, so is 8 bytes.
- * The int should be in the first 4, but our argument
- * frobbing has left it in the last 4.
- */
- u.val = *((int *)&arg + 1);
- err = sys_semctl (semid, semnum, cmd, u);
- break;
-
- case IPC_SET:
- if (version != IPC_64) {
- printk(KERN_WARNING
- "semctl(IPC_STAT(cmd=0x%x)) does not support libc5-style cmds\n",
- cmd);
- return -ENOSYS;
- }
- /* FALL THROUGH */
- case IPC_INFO:
- case SEM_INFO:
- case IPC_RMID:
- case GETVAL:
- case GETPID:
- case GETNCNT:
- case GETZCNT:
- case GETALL:
- case SETALL:
- err = sys_semctl (semid, semnum, cmd, arg);
- break;
-
- case IPC_STAT:
- case SEM_STAT:
- if (version != IPC_64) {
- printk(KERN_WARNING
- "semctl(IPC_STAT(cmd=0x%x)) does not support libc5-style cmds\n",
- cmd);
- return -ENOSYS;
- }
- u.buf = (struct semid_ds *)&s64;
- KERNEL_SYSCALL(err, sys_semctl, semid, semnum, cmd, u);
- if (err == 0) {
- return copyout_shmid64_ds32((struct shmid64_ds32 *)u.buf, &s64);
- }
- break;
-
- default:
- printk(KERN_WARNING "semctl(cmd=%d) undefined cmd\n", cmd);
- err = -ENOSYS;
- break;
- }
-
- return err;
-}
-
-asmlinkage long sys32_shmctl(int shmid, int cmd, struct shmid_ds *buf)
-{
- int err = -ENOSYS;
- struct shmid64_ds s64;
- int version = ipc_parse_version(&cmd);
-
- switch (cmd) {
- case IPC_INFO:
- if (version != IPC_64) {
- printk(KERN_WARNING
- "shmctl(IPC_INFO(cmd=0x%x)) does not support libc5 cmds\n",
- cmd);
- break;
- }
- /* WARNING: struct shminfo64 looks like it needs to contain
- * pointers, which on wide kernel might need to be wide.
- * If the struct is changed to contain long-longs, the progs
- * which use shmctl(IPC_INFO) (probably ipcls or something)
- * will need to be rebuilt.
- */
- err = sys_shmctl(shmid, cmd, buf);
- break;
-
- case SHM_STAT:
- case IPC_STAT:
- if (version != IPC_64) {
- printk(KERN_WARNING
- "shmctl(IPC_STAT(cmd=0x%x)) does not support libc5 cmds\n",
- cmd);
- break;
- }
- KERNEL_SYSCALL(err, sys_shmctl, shmid, cmd, (struct shmid_ds *)&s64);
- if (err == 0) {
- err = copyout_shmid64_ds32((struct shmid64_ds32 *)buf, &s64);
- }
- break;
- case IPC_SET:
- if (version != IPC_64) {
- printk(KERN_WARNING
- "shmctl(IPC_SET(cmd=0x%x)) does not support libc5 cmds\n",
- cmd);
- break;
- }
- /* FALL THROUGH */
- case SHM_INFO:
- default:
- err = sys_shmctl(shmid, cmd, buf);
- break;
- }
-
- return err;
-}
-
/* LFS */
extern asmlinkage long sys_truncate(const char *, loff_t);
Index: arch/parisc/kernel/syscall.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/syscall.S,v
retrieving revision 1.71
diff -u -r1.71 syscall.S
--- arch/parisc/kernel/syscall.S 2001/09/06 09:44:07 1.71
+++ arch/parisc/kernel/syscall.S 2001/11/23 00:16:55
@@ -577,15 +577,15 @@
ENTRY_DIFF(recvmsg)
ENTRY_SAME(semop) /* 185 */
ENTRY_SAME(semget)
- ENTRY_DIFF(semctl)
+ ENTRY_SAME(semctl_broken)
ENTRY_DIFF(msgsnd)
ENTRY_DIFF(msgrcv)
ENTRY_SAME(msgget) /* 190 */
- ENTRY_DIFF(msgctl)
+ ENTRY_SAME(msgctl_broken)
ENTRY_SAME(shmat_wrapper)
ENTRY_SAME(shmdt)
ENTRY_SAME(shmget)
- ENTRY_DIFF(shmctl) /* 195 */
+ ENTRY_SAME(shmctl_broken) /* 195 */
ENTRY_SAME(ni_syscall) /* streams1 */
ENTRY_SAME(ni_syscall) /* streams2 */
ENTRY_SAME(lstat64)
Index: include/asm-parisc/ipcbuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/ipcbuf.h,v
retrieving revision 1.3
diff -u -r1.3 ipcbuf.h
--- include/asm-parisc/ipcbuf.h 2001/02/27 00:48:51 1.3
+++ include/asm-parisc/ipcbuf.h 2001/11/22 00:19:50
@@ -15,8 +15,13 @@
gid_t gid;
uid_t cuid;
gid_t cgid;
+ unsigned short int __pad1;
mode_t mode;
- unsigned int seq;
+ unsigned short int __pad2;
+ unsigned short int seq;
+ unsigned int __pad3;
+ unsigned long long int __unused1;
+ unsigned long long int __unused2;
};
#endif /* __PARISC_IPCBUF_H__ */
Index: include/asm-parisc/shmbuf.h
===================================================================
RCS file: /home/cvs/parisc/linux/include/asm-parisc/shmbuf.h,v
retrieving revision 1.4
diff -u -r1.4 shmbuf.h
--- include/asm-parisc/shmbuf.h 2001/09/29 16:40:09 1.4
+++ include/asm-parisc/shmbuf.h 2001/11/22 00:27:34
@@ -13,7 +13,6 @@
struct shmid64_ds {
struct ipc64_perm shm_perm; /* operation perms */
- size_t shm_segsz; /* size of segment (bytes) */
#ifndef __LP64__
unsigned int __pad1;
#endif
@@ -26,6 +25,10 @@
unsigned int __pad3;
#endif
__kernel_time_t shm_ctime; /* last change time */
+#ifndef __LP64__
+ unsigned int __pad4;
+#endif
+ size_t shm_segsz; /* size of segment (bytes) */
__kernel_pid_t shm_cpid; /* pid of creator */
__kernel_pid_t shm_lpid; /* pid of last operator */
unsigned int shm_nattch; /* no. of current attaches */
Index: ipc/util.c
===================================================================
RCS file: /home/cvs/parisc/linux/ipc/util.c,v
retrieving revision 1.8
diff -u -r1.8 util.c
--- ipc/util.c 2001/08/17 06:12:21 1.8
+++ ipc/util.c 2001/11/20 23:17:01
@@ -312,7 +312,7 @@
out->seq = in->seq;
}
-#ifndef __ia64__
+#if !defined(__ia64__) && !defined(__hppa__)
/**
* ipc_parse_version - IPC call version
Index: ipc/util.h
===================================================================
RCS file: /home/cvs/parisc/linux/ipc/util.h,v
retrieving revision 1.5
diff -u -r1.5 util.h
--- ipc/util.h 2001/07/05 21:39:47 1.5
+++ ipc/util.h 2001/11/20 23:15:55
@@ -99,8 +99,8 @@
void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
-#ifdef __ia64__
- /* On IA-64, we always use the "64-bit version" of the IPC structures. */
+#if defined(__ia64__) || defined(__hppa__)
+ /* On IA-64 and PA-RISC, we always use the "64-bit version" of the IPC structures. */
# define ipc_parse_version(cmd) IPC_64
#else
int ipc_parse_version (int *cmd);
--
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea. [ Alexander Viro on linux-kernel ]