Index: sys/compat/linux/linux_ipc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_ipc.c,v retrieving revision 1.17.2.3 diff -u -p -r1.17.2.3 linux_ipc.c --- sys/compat/linux/linux_ipc.c 5 Nov 2001 19:08:22 -0000 1.17.2.3 +++ sys/compat/linux/linux_ipc.c 20 Oct 2003 18:09:17 -0000 @@ -381,7 +381,7 @@ linux_shmat(struct proc *p, struct linux bsd_args.shmid = args->shmid; bsd_args.shmaddr = args->shmaddr; bsd_args.shmflg = args->shmflg; - if ((error = shmat(p, &bsd_args))) + if ((error = shmat1(p, &bsd_args, 1))) return error; #ifdef __i386__ if ((error = copyout(p->p_retval, (caddr_t)args->raddr, sizeof(l_ulong)))) @@ -434,7 +434,7 @@ linux_shmctl(struct proc *p, struct linu bsd_args.shmid = args->shmid; bsd_args.cmd = IPC_STAT; bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); - if ((error = shmctl(p, &bsd_args))) + if ((error = shmctl1(p, &bsd_args, 1))) return error; bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid); return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid)); @@ -447,7 +447,7 @@ linux_shmctl(struct proc *p, struct linu linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf); bsd_args.shmid = args->shmid; bsd_args.cmd = IPC_SET; - return shmctl(p, &bsd_args); + return shmctl1(p, &bsd_args, 1); case LINUX_IPC_RMID: bsd_args.shmid = args->shmid; @@ -461,7 +461,7 @@ linux_shmctl(struct proc *p, struct linu bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds)); linux_to_bsd_shmid_ds(&linux_shmid, bsd_args.buf); } - return shmctl(p, &bsd_args); + return shmctl1(p, &bsd_args, 1); case LINUX_IPC_INFO: case LINUX_SHM_STAT: Index: sys/kern/sysv_shm.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sysv_shm.c,v retrieving revision 1.45.2.6 diff -u -p -r1.45.2.6 sysv_shm.c --- sys/kern/sysv_shm.c 22 Oct 2002 20:45:03 -0000 1.45.2.6 +++ sys/kern/sysv_shm.c 20 Oct 2003 20:35:55 -0000 @@ -91,7 +91,7 @@ struct shmmap_state { static void shm_deallocate_segment __P((struct shmid_ds *)); static int shm_find_segment_by_key __P((key_t)); -static struct shmid_ds *shm_find_segment_by_shmid __P((int)); +static struct shmid_ds *shm_find_segment_by_shmid __P((int, int)); static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); static void shmrealloc __P((void)); static void shminit __P((void *)); @@ -156,8 +156,9 @@ shm_find_segment_by_key(key) } static struct shmid_ds * -shm_find_segment_by_shmid(shmid) +shm_find_segment_by_shmid(shmid, wantrem) int shmid; + int wantrem; { int segnum; struct shmid_ds *shmseg; @@ -166,8 +167,8 @@ shm_find_segment_by_shmid(shmid) if (segnum < 0 || segnum >= shmalloced) return NULL; shmseg = &shmsegs[segnum]; - if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED)) - != SHMSEG_ALLOCATED || + if ((shmseg->shm_perm.mode & SHMSEG_ALLOCATED) == 0 || + (!wantrem && (shmseg->shm_perm.mode & SHMSEG_REMOVED) != 0) || shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid)) return NULL; return shmseg; @@ -253,9 +254,10 @@ struct shmat_args { #endif int -shmat(p, uap) +shmat1(p, uap, wantrem) struct proc *p; struct shmat_args *uap; + int wantrem; { int error, i, flags; struct shmid_ds *shmseg; @@ -277,7 +279,7 @@ shmat(p, uap) shmmap_s[i].shmid = -1; p->p_vmspace->vm_shm = (caddr_t)shmmap_s; } - shmseg = shm_find_segment_by_shmid(uap->shmid); + shmseg = shm_find_segment_by_shmid(uap->shmid, wantrem); if (shmseg == NULL) return EINVAL; error = ipcperm(p, &shmseg->shm_perm, @@ -332,6 +334,14 @@ shmat(p, uap) return 0; } +int +shmat(p, uap) + struct proc *p; + struct shmat_args *uap; +{ + return shmat1(p, uap, 0); +} + struct oshmid_ds { struct ipc_perm shm_perm; /* operation perms */ int shm_segsz; /* size of segment (bytes) */ @@ -363,7 +373,7 @@ oshmctl(p, uap) if (!jail_sysvipc_allowed && p->p_prison != NULL) return (ENOSYS); - shmseg = shm_find_segment_by_shmid(uap->shmid); + shmseg = shm_find_segment_by_shmid(uap->shmid, 0); if (shmseg == NULL) return EINVAL; switch (uap->cmd) { @@ -403,9 +413,10 @@ struct shmctl_args { #endif int -shmctl(p, uap) +shmctl1(p, uap, wantrem) struct proc *p; struct shmctl_args *uap; + int wantrem; { int error; struct shmid_ds inbuf; @@ -414,7 +425,7 @@ shmctl(p, uap) if (!jail_sysvipc_allowed && p->p_prison != NULL) return (ENOSYS); - shmseg = shm_find_segment_by_shmid(uap->shmid); + shmseg = shm_find_segment_by_shmid(uap->shmid, wantrem); if (shmseg == NULL) return EINVAL; switch (uap->cmd) { @@ -459,6 +470,14 @@ shmctl(p, uap) return EINVAL; } return 0; +} + +int +shmctl(p, uap) + struct proc *p; + struct shmctl_args *uap; +{ + return shmctl1(p, uap, 0); } #ifndef _SYS_SYSPROTO_H_ Index: sys/sys/sysproto.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sysproto.h,v retrieving revision 1.59.2.10 diff -u -p -r1.59.2.10 sysproto.h --- sys/sys/sysproto.h 12 Jul 2002 08:23:08 -0000 1.59.2.10 +++ sys/sys/sysproto.h 20 Oct 2003 18:20:38 -0000 @@ -1170,7 +1170,9 @@ int msgctl __P((struct proc *, struct ms int msgget __P((struct proc *, struct msgget_args *)); int msgsnd __P((struct proc *, struct msgsnd_args *)); int msgrcv __P((struct proc *, struct msgrcv_args *)); +int shmat1 __P((struct proc *, struct shmat_args *, int wantrem)); int shmat __P((struct proc *, struct shmat_args *)); +int shmctl1 __P((struct proc *, struct shmctl_args *, int wantrem)); int shmctl __P((struct proc *, struct shmctl_args *)); int shmdt __P((struct proc *, struct shmdt_args *)); int shmget __P((struct proc *, struct shmget_args *));