[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 ]