syscall messaging 3: Expand the 'header' that goes in front of the syscall
[dragonfly.git] / sys / kern / sysv_shm.c
index 4f680c6..9205ae8 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/kern/sysv_shm.c,v 1.45.2.6 2002/10/22 20:45:03 fjoe Exp $ */
-/* $DragonFly: src/sys/kern/sysv_shm.c,v 1.2 2003/06/17 04:28:41 dillon Exp $ */
+/* $DragonFly: src/sys/kern/sysv_shm.c,v 1.9 2003/07/30 00:19:14 dillon Exp $ */
 /*     $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $      */
 
 /*
@@ -93,7 +93,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 int shm_delete_mapping __P((struct proc *, struct shmmap_state *));
+static int shm_delete_mapping __P((struct vmspace *vm, struct shmmap_state *));
 static void shmrealloc __P((void));
 static void shminit __P((void *));
 
@@ -192,9 +192,7 @@ shm_deallocate_segment(shmseg)
 }
 
 static int
-shm_delete_mapping(p, shmmap_s)
-       struct proc *p;
-       struct shmmap_state *shmmap_s;
+shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
 {
        struct shmid_ds *shmseg;
        int segnum, result;
@@ -203,7 +201,7 @@ shm_delete_mapping(p, shmmap_s)
        segnum = IPCID_TO_IX(shmmap_s->shmid);
        shmseg = &shmsegs[segnum];
        size = round_page(shmseg->shm_segsz);
-       result = vm_map_remove(&p->p_vmspace->vm_map, shmmap_s->va, shmmap_s->va + size);
+       result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
        if (result != KERN_SUCCESS)
                return EINVAL;
        shmmap_s->shmid = -1;
@@ -216,21 +214,14 @@ shm_delete_mapping(p, shmmap_s)
        return 0;
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct shmdt_args {
-       void *shmaddr;
-};
-#endif
-
 int
-shmdt(p, uap)
-       struct proc *p;
-       struct shmdt_args *uap;
+shmdt(struct shmdt_args *uap)
 {
+       struct proc *p = curproc;
        struct shmmap_state *shmmap_s;
        int i;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
        shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
@@ -242,22 +233,13 @@ shmdt(p, uap)
                        break;
        if (i == shminfo.shmseg)
                return EINVAL;
-       return shm_delete_mapping(p, shmmap_s);
+       return shm_delete_mapping(p->p_vmspace, shmmap_s);
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct shmat_args {
-       int shmid;
-       void *shmaddr;
-       int shmflg;
-};
-#endif
-
 int
-shmat(p, uap)
-       struct proc *p;
-       struct shmat_args *uap;
+shmat(struct shmat_args *uap)
 {
+       struct proc *p = curproc;
        int error, i, flags;
        struct shmid_ds *shmseg;
        struct shmmap_state *shmmap_s = NULL;
@@ -267,7 +249,7 @@ shmat(p, uap)
        vm_size_t size;
        int rv;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
        shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
@@ -329,7 +311,7 @@ shmat(p, uap)
        shmseg->shm_lpid = p->p_pid;
        shmseg->shm_atime = time_second;
        shmseg->shm_nattch++;
-       p->p_retval[0] = attach_va;
+       uap->sysmsg_result = attach_va;
        return 0;
 }
 
@@ -346,6 +328,7 @@ struct oshmid_ds {
 };
 
 struct oshmctl_args {
+       union sysmsg sysmsg;
        int shmid;
        int cmd;
        struct oshmid_ds *ubuf;
@@ -361,7 +344,7 @@ oshmctl(p, uap)
        struct shmid_ds *shmseg;
        struct oshmid_ds outbuf;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
        shmseg = shm_find_segment_by_shmid(uap->shmid);
@@ -387,7 +370,7 @@ oshmctl(p, uap)
                break;
        default:
                /* XXX casting to (sy_call_t *) is bogus, as usual. */
-               return ((sy_call_t *)shmctl)(p, uap);
+               return ((sy_call_t *)shmctl)(uap);
        }
        return 0;
 #else
@@ -395,24 +378,15 @@ oshmctl(p, uap)
 #endif
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct shmctl_args {
-       int shmid;
-       int cmd;
-       struct shmid_ds *buf;
-};
-#endif
-
 int
-shmctl(p, uap)
-       struct proc *p;
-       struct shmctl_args *uap;
+shmctl(struct shmctl_args *uap)
 {
+       struct proc *p = curproc;
        int error;
        struct shmid_ds inbuf;
        struct shmid_ds *shmseg;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
        shmseg = shm_find_segment_by_shmid(uap->shmid);
@@ -462,14 +436,6 @@ shmctl(p, uap)
        return 0;
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct shmget_args {
-       key_t key;
-       size_t size;
-       int shmflg;
-};
-#endif
-
 static int
 shmget_existing(p, uap, mode, segnum)
        struct proc *p;
@@ -488,7 +454,7 @@ shmget_existing(p, uap, mode, segnum)
                 * allocation failed or it was freed).
                 */
                shmseg->shm_perm.mode |= SHMSEG_WANTED;
-               error = tsleep((caddr_t)shmseg, PLOCK | PCATCH, "shmget", 0);
+               error = tsleep((caddr_t)shmseg, PCATCH, "shmget", 0);
                if (error)
                        return error;
                return EAGAIN;
@@ -500,7 +466,7 @@ shmget_existing(p, uap, mode, segnum)
                return error;
        if (uap->size && uap->size > shmseg->shm_segsz)
                return EINVAL;
-       p->p_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
+       uap->sysmsg_result = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
        return 0;
 }
 
@@ -580,18 +546,17 @@ shmget_allocate_segment(p, uap, mode)
                shmseg->shm_perm.mode &= ~SHMSEG_WANTED;
                wakeup((caddr_t)shmseg);
        }
-       p->p_retval[0] = shmid;
+       uap->sysmsg_result = shmid;
        return 0;
 }
 
 int
-shmget(p, uap)
-       struct proc *p;
-       struct shmget_args *uap;
+shmget(struct shmget_args *uap)
 {
+       struct proc *p = curproc;
        int segnum, mode, error;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
        mode = uap->shmflg & ACCESSPERMS;
@@ -610,24 +575,25 @@ shmget(p, uap)
        return shmget_allocate_segment(p, uap, mode);
 }
 
+/*
+ *  shmsys_args(u_int which, int a2, ...) (VARARGS)
+ */
 int
-shmsys(p, uap)
-       struct proc *p;
-       /* XXX actually varargs. */
-       struct shmsys_args /* {
-               u_int   which;
-               int     a2;
-               int     a3;
-               int     a4;
-       } */ *uap;
+shmsys(struct shmsys_args *uap)
 {
+       struct proc *p = curproc;
+       int which = uap->which;
+       int error;
 
-       if (!jail_sysvipc_allowed && p->p_prison != NULL)
+       if (!jail_sysvipc_allowed && p->p_ucred->cr_prison != NULL)
                return (ENOSYS);
 
-       if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
+       if (which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
                return EINVAL;
-       return ((*shmcalls[uap->which])(p, &uap->a2));
+       bcopy(&uap->a2, &uap->which,
+               sizeof(struct shmsys_args) - offsetof(struct shmsys_args, a2));
+       error = ((*shmcalls[which])(uap));
+       return(error);
 }
 
 void
@@ -648,18 +614,19 @@ shmfork(p1, p2)
 }
 
 void
-shmexit(p)
-       struct proc *p;
+shmexit(struct vmspace *vm)
 {
-       struct shmmap_state *shmmap_s;
+       struct shmmap_state *base, *shm;
        int i;
 
-       shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
-       for (i = 0; i < shminfo.shmseg; i++, shmmap_s++)
-               if (shmmap_s->shmid != -1)
-                       shm_delete_mapping(p, shmmap_s);
-       free((caddr_t)p->p_vmspace->vm_shm, M_SHM);
-       p->p_vmspace->vm_shm = NULL;
+       if ((base = (struct shmmap_state *)vm->vm_shm) != NULL) {
+               vm->vm_shm = NULL;
+               for (i = 0, shm = base; i < shminfo.shmseg; i++, shm++) {
+                       if (shm->shmid != -1)
+                               shm_delete_mapping(vm, shm);
+               }
+               free(base, M_SHM);
+       }
 }
 
 static void