[parisc-linux-cvs] wrapper for shmctl()

bame@riverrock.org bame@riverrock.org
Thu, 01 Mar 2001 10:13:33 -0700


Index: arch/parisc/kernel/syscall.S
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/syscall.S,v
retrieving revision 1.57
diff -u -r1.57 syscall.S
--- syscall.S	2001/02/27 00:48:50	1.57
+++ syscall.S	2001/03/01 17:04:44
@@ -554,8 +554,7 @@
 	ENTRY_SAME(shmdt)
 	ENTRY_SAME(shmget)
 	/***************/
-	/* struct shmid_ds contains pointers */
-	ENTRY_UHOH(shmctl)		/* 195 */
+	ENTRY_DIFF(shmctl)		/* 195 */
 	ENTRY_SAME(ni_syscall)		/* streams1 */
 	ENTRY_SAME(ni_syscall)		/* streams2 */
 
Index: arch/parisc64/kernel/sys_parisc32.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc64/kernel/sys_parisc32.c,v
retrieving revision 1.17
diff -u -r1.17 sys_parisc32.c
--- sys_parisc32.c	2001/02/27 00:48:50	1.17
+++ sys_parisc32.c	2001/03/01 17:04:45
@@ -2573,6 +2573,20 @@
 	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;
@@ -2607,19 +2621,10 @@
 			printk("semctl(IPC_STAT(cmd=0x%x)) does not support libc5-style cmds\n", cmd);
 			return ENOSYS;
 		}
-		u.buf = &s64;
+		u.buf = (struct semid_ds *)&s64;
 		KERNEL_SYSCALL(err, sys_semctl, semid, semnum, cmd, u);
 		if (err == 0) {
-			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((struct shmid64_ds32 *)arg.buf, &s32, sizeof s32);
+			return copyout_shmid64_ds32((struct shmid64_ds32 *)u.buf, &s64);
 		}
 		break;
 
@@ -2627,6 +2632,53 @@
 		printk("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("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("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("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;