Overhaul of the SVID IPC facilities, primarily to use the types specified
by the Single UNIX Specification version 2, rather than the SVR2-derived types. While I was here, I did a namespace sweep to expose the constants and strucutures, and structure members described by SUSv2; documentation updates coming shortly. Fixes kern/8158.
This commit is contained in:
parent
0174ee34d0
commit
dc8ecaa15b
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: kern_allocsys.c,v 1.4 1999/06/01 00:40:48 lukem Exp $ */
|
||||
/* $NetBSD: kern_allocsys.c,v 1.5 1999/08/25 05:05:48 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
@ -139,14 +139,14 @@ allocsys(v, mdcallback)
|
||||
#endif
|
||||
#ifdef SYSVSEM
|
||||
ALLOCSYS(v, sema, struct semid_ds, seminfo.semmni);
|
||||
ALLOCSYS(v, sem, struct sem, seminfo.semmns);
|
||||
ALLOCSYS(v, sem, struct __sem, seminfo.semmns);
|
||||
/* This is pretty disgusting! */
|
||||
ALLOCSYS(v, semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
|
||||
#endif
|
||||
#ifdef SYSVMSG
|
||||
ALLOCSYS(v, msgpool, char, msginfo.msgmax);
|
||||
ALLOCSYS(v, msgmaps, struct msgmap, msginfo.msgseg);
|
||||
ALLOCSYS(v, msghdrs, struct msg, msginfo.msgtql);
|
||||
ALLOCSYS(v, msghdrs, struct __msg, msginfo.msgtql);
|
||||
ALLOCSYS(v, msqids, struct msqid_ds, msginfo.msgmni);
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
$NetBSD: syscalls.master,v 1.96 1999/07/12 23:01:27 thorpej Exp $
|
||||
$NetBSD: syscalls.master,v 1.97 1999/08/25 05:05:48 thorpej Exp $
|
||||
|
||||
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
|
||||
|
||||
@ -426,28 +426,28 @@
|
||||
#endif /* !LKM */
|
||||
; System calls 220-300 are reserved for use by NetBSD
|
||||
#if defined(SYSVSEM) || !defined(_KERNEL)
|
||||
220 STD { int sys___semctl(int semid, int semnum, int cmd, \
|
||||
union semun *arg); }
|
||||
220 COMPAT_14 { int sys___semctl(int semid, int semnum, int cmd, \
|
||||
union __semun *arg); }
|
||||
221 STD { int sys_semget(key_t key, int nsems, int semflg); }
|
||||
222 STD { int sys_semop(int semid, struct sembuf *sops, \
|
||||
size_t nsops); }
|
||||
223 STD { int sys_semconfig(int flag); }
|
||||
#else
|
||||
220 EXCL semctl
|
||||
220 EXCL compat_14_semctl
|
||||
221 EXCL semget
|
||||
222 EXCL semop
|
||||
223 EXCL semconfig
|
||||
#endif
|
||||
#if defined(SYSVMSG) || !defined(_KERNEL)
|
||||
224 STD { int sys_msgctl(int msqid, int cmd, \
|
||||
struct msqid_ds *buf); }
|
||||
224 COMPAT_14 { int sys_msgctl(int msqid, int cmd, \
|
||||
struct msqid_ds14 *buf); }
|
||||
225 STD { int sys_msgget(key_t key, int msgflg); }
|
||||
226 STD { int sys_msgsnd(int msqid, const void *msgp, \
|
||||
size_t msgsz, int msgflg); }
|
||||
227 STD { ssize_t sys_msgrcv(int msqid, void *msgp, \
|
||||
size_t msgsz, long msgtyp, int msgflg); }
|
||||
#else
|
||||
224 EXCL msgctl
|
||||
224 EXCL compat_14_msgctl
|
||||
225 EXCL msgget
|
||||
226 EXCL msgsnd
|
||||
227 EXCL msgrcv
|
||||
@ -455,13 +455,13 @@
|
||||
#if defined(SYSVSHM) || !defined(_KERNEL)
|
||||
228 STD { void *sys_shmat(int shmid, const void *shmaddr, \
|
||||
int shmflg); }
|
||||
229 STD { int sys_shmctl(int shmid, int cmd, \
|
||||
struct shmid_ds *buf); }
|
||||
229 COMPAT_14 { int sys_shmctl(int shmid, int cmd, \
|
||||
struct shmid_ds14 *buf); }
|
||||
230 STD { int sys_shmdt(const void *shmaddr); }
|
||||
231 STD { int sys_shmget(key_t key, size_t size, int shmflg); }
|
||||
#else
|
||||
228 EXCL shmat
|
||||
229 EXCL shmctl
|
||||
229 EXCL compat_14_shmctl
|
||||
230 EXCL shmdt
|
||||
231 EXCL shmget
|
||||
#endif
|
||||
@ -565,3 +565,21 @@
|
||||
struct stat *sb); }
|
||||
300 STD { int sys_fhstatfs(const fhandle_t *fhp, \
|
||||
struct statfs *buf); }
|
||||
#if defined(SYSVSEM) || !defined(_KERNEL)
|
||||
301 STD { int sys___semctl13(int semid, int semnum, int cmd, \
|
||||
union __semun arg); }
|
||||
#else
|
||||
301 EXCL __semctl13
|
||||
#endif
|
||||
#if defined(SYSVMSG) || !defined(_KERNEL)
|
||||
302 STD { int sys___msgctl13(int msqid, int cmd, \
|
||||
struct msqid_ds *buf); }
|
||||
#else
|
||||
302 EXCL __msgctl13
|
||||
#endif
|
||||
#if defined(SYSVSHM) || !defined(_KERNEL)
|
||||
303 STD { int sys___shmctl13(int shmid, int cmd, \
|
||||
struct shmid_ds *buf); }
|
||||
#else
|
||||
303 EXCL __shmctl13
|
||||
#endif
|
||||
|
@ -1,9 +1,46 @@
|
||||
/* $NetBSD: sysv_msg.c,v 1.25 1999/04/21 02:31:50 mrg Exp $ */
|
||||
/* $NetBSD: sysv_msg.c,v 1.26 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation of SVID messages
|
||||
*
|
||||
* Author: Daniel Boulet
|
||||
* Author: Daniel Boulet
|
||||
*
|
||||
* Copyright 1993 Daniel Boulet and RTMX Inc.
|
||||
*
|
||||
@ -42,9 +79,9 @@
|
||||
|
||||
int nfree_msgmaps; /* # of free map entries */
|
||||
short free_msgmaps; /* head of linked list of free map entries */
|
||||
struct msg *free_msghdrs; /* list of free msg headers */
|
||||
struct __msg *free_msghdrs; /* list of free msg headers */
|
||||
|
||||
static void msg_freehdr __P((struct msg *));
|
||||
static void msg_freehdr __P((struct __msg *));
|
||||
|
||||
void
|
||||
msginit()
|
||||
@ -98,13 +135,13 @@ msginit()
|
||||
|
||||
for (i = 0; i < msginfo.msgmni; i++) {
|
||||
msqids[i].msg_qbytes = 0; /* implies entry is available */
|
||||
msqids[i].msg_perm.seq = 0; /* reset to a known value */
|
||||
msqids[i].msg_perm._seq = 0; /* reset to a known value */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
msg_freehdr(msghdr)
|
||||
struct msg *msghdr;
|
||||
struct __msg *msghdr;
|
||||
{
|
||||
while (msghdr->msg_ts > 0) {
|
||||
short next;
|
||||
@ -127,121 +164,135 @@ msg_freehdr(msghdr)
|
||||
}
|
||||
|
||||
int
|
||||
sys_msgctl(p, v, retval)
|
||||
sys___msgctl13(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
register struct sys_msgctl_args /* {
|
||||
struct sys___msgctl13_args /* {
|
||||
syscallarg(int) msqid;
|
||||
syscallarg(int) cmd;
|
||||
syscallarg(struct msqid_ds *) buf;
|
||||
} */ *uap = v;
|
||||
int msqid = SCARG(uap, msqid);
|
||||
int cmd = SCARG(uap, cmd);
|
||||
struct msqid_ds *user_msqptr = SCARG(uap, buf);
|
||||
struct ucred *cred = p->p_ucred;
|
||||
int rval, eval;
|
||||
struct msqid_ds msqbuf;
|
||||
register struct msqid_ds *msqptr;
|
||||
int cmd, error;
|
||||
|
||||
MSG_PRINTF(("call to msgctl(%d, %d, %p)\n", msqid, cmd, user_msqptr));
|
||||
cmd = SCARG(uap, cmd);
|
||||
|
||||
msqid = IPCID_TO_IX(msqid);
|
||||
|
||||
if (msqid < 0 || msqid >= msginfo.msgmni) {
|
||||
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni));
|
||||
return(EINVAL);
|
||||
if (cmd == IPC_SET) {
|
||||
error = copyin(SCARG(uap, buf), &msqbuf, sizeof(msqbuf));
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
error = msgctl1(p, SCARG(uap, msqid), cmd,
|
||||
(cmd == IPC_SET || cmd == IPC_STAT) ? &msqbuf : NULL);
|
||||
|
||||
if (error == 0 && cmd == IPC_STAT)
|
||||
error = copyout(&msqbuf, SCARG(uap, buf), sizeof(msqbuf));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
msgctl1(p, msqid, cmd, msqbuf)
|
||||
struct proc *p;
|
||||
int msqid;
|
||||
int cmd;
|
||||
struct msqid_ds *msqbuf;
|
||||
{
|
||||
struct ucred *cred = p->p_ucred;
|
||||
struct msqid_ds *msqptr;
|
||||
int error = 0, ix;
|
||||
|
||||
MSG_PRINTF(("call to msgctl1(%d, %d)\n", msqid, cmd));
|
||||
|
||||
ix = IPCID_TO_IX(msqid);
|
||||
|
||||
if (ix < 0 || ix >= msginfo.msgmni) {
|
||||
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", ix,
|
||||
msginfo.msgmni));
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
msqptr = &msqids[ix];
|
||||
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
MSG_PRINTF(("no such msqid\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
if (msqptr->msg_perm._seq != IPCID_TO_SEQ(msqid)) {
|
||||
MSG_PRINTF(("wrong sequence number\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
eval = 0;
|
||||
rval = 0;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case IPC_RMID:
|
||||
{
|
||||
struct msg *msghdr;
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0)
|
||||
return(eval);
|
||||
struct __msg *msghdr;
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)) != 0)
|
||||
return (error);
|
||||
/* Free the message headers */
|
||||
msghdr = msqptr->msg_first;
|
||||
msghdr = msqptr->_msg_first;
|
||||
while (msghdr != NULL) {
|
||||
struct msg *msghdr_tmp;
|
||||
struct __msg *msghdr_tmp;
|
||||
|
||||
/* Free the segments of each message */
|
||||
msqptr->msg_cbytes -= msghdr->msg_ts;
|
||||
msqptr->_msg_cbytes -= msghdr->msg_ts;
|
||||
msqptr->msg_qnum--;
|
||||
msghdr_tmp = msghdr;
|
||||
msghdr = msghdr->msg_next;
|
||||
msg_freehdr(msghdr_tmp);
|
||||
}
|
||||
|
||||
if (msqptr->msg_cbytes != 0)
|
||||
if (msqptr->_msg_cbytes != 0)
|
||||
panic("msg_cbytes is screwed up");
|
||||
if (msqptr->msg_qnum != 0)
|
||||
panic("msg_qnum is screwed up");
|
||||
|
||||
msqptr->msg_qbytes = 0; /* Mark it as free */
|
||||
|
||||
wakeup((caddr_t)msqptr);
|
||||
wakeup(msqptr);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case IPC_SET:
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
|
||||
return(eval);
|
||||
if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
|
||||
return(eval);
|
||||
if (msqbuf.msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
|
||||
return(EPERM);
|
||||
if (msqbuf.msg_qbytes > msginfo.msgmnb) {
|
||||
MSG_PRINTF(("can't increase msg_qbytes beyond %d (truncating)\n",
|
||||
msginfo.msgmnb));
|
||||
msqbuf.msg_qbytes = msginfo.msgmnb; /* silently restrict qbytes to system limit */
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_M)))
|
||||
return (error);
|
||||
if (msqbuf->msg_qbytes > msqptr->msg_qbytes && cred->cr_uid != 0)
|
||||
return (EPERM);
|
||||
if (msqbuf->msg_qbytes > msginfo.msgmnb) {
|
||||
MSG_PRINTF(("can't increase msg_qbytes beyond %d "
|
||||
"(truncating)\n", msginfo.msgmnb));
|
||||
/* silently restrict qbytes to system limit */
|
||||
msqbuf->msg_qbytes = msginfo.msgmnb;
|
||||
}
|
||||
if (msqbuf.msg_qbytes == 0) {
|
||||
if (msqbuf->msg_qbytes == 0) {
|
||||
MSG_PRINTF(("can't reduce msg_qbytes to 0\n"));
|
||||
return(EINVAL); /* non-standard errno! */
|
||||
return (EINVAL); /* XXX non-standard errno! */
|
||||
}
|
||||
msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
|
||||
msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
|
||||
msqptr->msg_perm.uid = msqbuf->msg_perm.uid;
|
||||
msqptr->msg_perm.gid = msqbuf->msg_perm.gid;
|
||||
msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) |
|
||||
(msqbuf.msg_perm.mode & 0777);
|
||||
msqptr->msg_qbytes = msqbuf.msg_qbytes;
|
||||
(msqbuf->msg_perm.mode & 0777);
|
||||
msqptr->msg_qbytes = msqbuf->msg_qbytes;
|
||||
msqptr->msg_ctime = time.tv_sec;
|
||||
break;
|
||||
|
||||
case IPC_STAT:
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
|
||||
MSG_PRINTF(("requester doesn't have read access\n"));
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
eval = copyout((caddr_t)msqptr, user_msqptr,
|
||||
sizeof(struct msqid_ds));
|
||||
memcpy(msqbuf, msqptr, sizeof(struct msqid_ds));
|
||||
break;
|
||||
|
||||
default:
|
||||
MSG_PRINTF(("invalid command %d\n", cmd));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (eval == 0)
|
||||
*retval = rval;
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
@ -250,15 +301,15 @@ sys_msgget(p, v, retval)
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
register struct sys_msgget_args /* {
|
||||
struct sys_msgget_args /* {
|
||||
syscallarg(key_t) key;
|
||||
syscallarg(int) msgflg;
|
||||
} */ *uap = v;
|
||||
int msqid, eval;
|
||||
int msqid, error;
|
||||
int key = SCARG(uap, key);
|
||||
int msgflg = SCARG(uap, msgflg);
|
||||
struct ucred *cred = p->p_ucred;
|
||||
register struct msqid_ds *msqptr = NULL;
|
||||
struct msqid_ds *msqptr = NULL;
|
||||
|
||||
MSG_PRINTF(("msgget(0x%x, 0%o)\n", key, msgflg));
|
||||
|
||||
@ -266,7 +317,7 @@ sys_msgget(p, v, retval)
|
||||
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
|
||||
msqptr = &msqids[msqid];
|
||||
if (msqptr->msg_qbytes != 0 &&
|
||||
msqptr->msg_perm.key == key)
|
||||
msqptr->msg_perm._key == key)
|
||||
break;
|
||||
}
|
||||
if (msqid < msginfo.msgmni) {
|
||||
@ -275,10 +326,11 @@ sys_msgget(p, v, retval)
|
||||
MSG_PRINTF(("not exclusive\n"));
|
||||
return(EEXIST);
|
||||
}
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, msgflg & 0700 ))) {
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm,
|
||||
msgflg & 0700 ))) {
|
||||
MSG_PRINTF(("requester doesn't have 0%o access\n",
|
||||
msgflg & 0700));
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
@ -300,20 +352,20 @@ sys_msgget(p, v, retval)
|
||||
}
|
||||
if (msqid == msginfo.msgmni) {
|
||||
MSG_PRINTF(("no more msqid_ds's available\n"));
|
||||
return(ENOSPC);
|
||||
return (ENOSPC);
|
||||
}
|
||||
MSG_PRINTF(("msqid %d is available\n", msqid));
|
||||
msqptr->msg_perm.key = key;
|
||||
msqptr->msg_perm._key = key;
|
||||
msqptr->msg_perm.cuid = cred->cr_uid;
|
||||
msqptr->msg_perm.uid = cred->cr_uid;
|
||||
msqptr->msg_perm.cgid = cred->cr_gid;
|
||||
msqptr->msg_perm.gid = cred->cr_gid;
|
||||
msqptr->msg_perm.mode = (msgflg & 0777);
|
||||
/* Make sure that the returned msqid is unique */
|
||||
msqptr->msg_perm.seq++;
|
||||
msqptr->msg_first = NULL;
|
||||
msqptr->msg_last = NULL;
|
||||
msqptr->msg_cbytes = 0;
|
||||
msqptr->msg_perm._seq++;
|
||||
msqptr->_msg_first = NULL;
|
||||
msqptr->_msg_last = NULL;
|
||||
msqptr->_msg_cbytes = 0;
|
||||
msqptr->msg_qnum = 0;
|
||||
msqptr->msg_qbytes = msginfo.msgmnb;
|
||||
msqptr->msg_lspid = 0;
|
||||
@ -323,13 +375,13 @@ sys_msgget(p, v, retval)
|
||||
msqptr->msg_ctime = time.tv_sec;
|
||||
} else {
|
||||
MSG_PRINTF(("didn't find it and wasn't asked to create it\n"));
|
||||
return(ENOENT);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
found:
|
||||
found:
|
||||
/* Construct the unique msqid */
|
||||
*retval = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -338,7 +390,7 @@ sys_msgsnd(p, v, retval)
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
register struct sys_msgsnd_args /* {
|
||||
struct sys_msgsnd_args /* {
|
||||
syscallarg(int) msqid;
|
||||
syscallarg(const void *) msgp;
|
||||
syscallarg(size_t) msgsz;
|
||||
@ -348,10 +400,10 @@ sys_msgsnd(p, v, retval)
|
||||
const char *user_msgp = SCARG(uap, msgp);
|
||||
size_t msgsz = SCARG(uap, msgsz);
|
||||
int msgflg = SCARG(uap, msgflg);
|
||||
int segs_needed, eval;
|
||||
int segs_needed, error;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
register struct msqid_ds *msqptr;
|
||||
register struct msg *msghdr;
|
||||
struct msqid_ds *msqptr;
|
||||
struct __msg *msghdr;
|
||||
short next;
|
||||
|
||||
MSG_PRINTF(("call to msgsnd(%d, %p, %d, %d)\n", msqid, user_msgp, msgsz,
|
||||
@ -362,27 +414,27 @@ sys_msgsnd(p, v, retval)
|
||||
if (msqid < 0 || msqid >= msginfo.msgmni) {
|
||||
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
MSG_PRINTF(("no such message queue id\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
if (msqptr->msg_perm._seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
MSG_PRINTF(("wrong sequence number\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_W))) {
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_W))) {
|
||||
MSG_PRINTF(("requester doesn't have write access\n"));
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
|
||||
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
|
||||
MSG_PRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz, msginfo.msgssz,
|
||||
segs_needed));
|
||||
MSG_PRINTF(("msgsz=%d, msgssz=%d, segs_needed=%d\n", msgsz,
|
||||
msginfo.msgssz, segs_needed));
|
||||
for (;;) {
|
||||
int need_more_resources = 0;
|
||||
|
||||
@ -393,14 +445,14 @@ sys_msgsnd(p, v, retval)
|
||||
|
||||
if (msgsz > msqptr->msg_qbytes) {
|
||||
MSG_PRINTF(("msgsz > msqptr->msg_qbytes\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (msqptr->msg_perm.mode & MSG_LOCKED) {
|
||||
MSG_PRINTF(("msqid is locked\n"));
|
||||
need_more_resources = 1;
|
||||
}
|
||||
if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes) {
|
||||
if (msgsz + msqptr->_msg_cbytes > msqptr->msg_qbytes) {
|
||||
MSG_PRINTF(("msgsz + msg_cbytes > msg_qbytes\n"));
|
||||
need_more_resources = 1;
|
||||
}
|
||||
@ -417,8 +469,9 @@ sys_msgsnd(p, v, retval)
|
||||
int we_own_it;
|
||||
|
||||
if ((msgflg & IPC_NOWAIT) != 0) {
|
||||
MSG_PRINTF(("need more resources but caller doesn't want to wait\n"));
|
||||
return(EAGAIN);
|
||||
MSG_PRINTF(("need more resources but caller "
|
||||
"doesn't want to wait\n"));
|
||||
return (EAGAIN);
|
||||
}
|
||||
|
||||
if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
|
||||
@ -432,14 +485,15 @@ sys_msgsnd(p, v, retval)
|
||||
we_own_it = 1;
|
||||
}
|
||||
MSG_PRINTF(("goodnight\n"));
|
||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
|
||||
error = tsleep(msqptr, (PZERO - 4) | PCATCH,
|
||||
"msgwait", 0);
|
||||
MSG_PRINTF(("good morning, eval=%d\n", eval));
|
||||
MSG_PRINTF(("good morning, error=%d\n", error));
|
||||
if (we_own_it)
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
if (eval != 0) {
|
||||
MSG_PRINTF(("msgsnd: interrupted system call\n"));
|
||||
return(EINTR);
|
||||
if (error != 0) {
|
||||
MSG_PRINTF(("msgsnd: interrupted system "
|
||||
"call\n"));
|
||||
return (EINTR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -450,14 +504,13 @@ sys_msgsnd(p, v, retval)
|
||||
MSG_PRINTF(("msqid deleted\n"));
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
return (EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code
|
||||
yet! */
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
MSG_PRINTF(("got all the resources that we need\n"));
|
||||
break;
|
||||
@ -473,7 +526,7 @@ sys_msgsnd(p, v, retval)
|
||||
panic("msg_perm.mode & MSG_LOCKED");
|
||||
if (segs_needed > nfree_msgmaps)
|
||||
panic("segs_needed > nfree_msgmaps");
|
||||
if (msgsz + msqptr->msg_cbytes > msqptr->msg_qbytes)
|
||||
if (msgsz + msqptr->_msg_cbytes > msqptr->msg_qbytes)
|
||||
panic("msgsz + msg_cbytes > msg_qbytes");
|
||||
if (free_msghdrs == NULL)
|
||||
panic("no more msghdrs");
|
||||
@ -522,13 +575,13 @@ sys_msgsnd(p, v, retval)
|
||||
* Copy in the message type
|
||||
*/
|
||||
|
||||
if ((eval = copyin(user_msgp, &msghdr->msg_type,
|
||||
if ((error = copyin(user_msgp, &msghdr->msg_type,
|
||||
sizeof(msghdr->msg_type))) != 0) {
|
||||
MSG_PRINTF(("error %d copying the message type\n", eval));
|
||||
MSG_PRINTF(("error %d copying the message type\n", error));
|
||||
msg_freehdr(msghdr);
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
wakeup(msqptr);
|
||||
return (error);
|
||||
}
|
||||
user_msgp += sizeof(msghdr->msg_type);
|
||||
|
||||
@ -539,9 +592,9 @@ sys_msgsnd(p, v, retval)
|
||||
if (msghdr->msg_type < 1) {
|
||||
msg_freehdr(msghdr);
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
wakeup((caddr_t)msqptr);
|
||||
wakeup(msqptr);
|
||||
MSG_PRINTF(("mtype (%d) < 1\n", msghdr->msg_type));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -559,13 +612,14 @@ sys_msgsnd(p, v, retval)
|
||||
panic("next too low #2");
|
||||
if (next >= msginfo.msgseg)
|
||||
panic("next out of range #2");
|
||||
if ((eval = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
|
||||
if ((error = copyin(user_msgp, &msgpool[next * msginfo.msgssz],
|
||||
tlen)) != 0) {
|
||||
MSG_PRINTF(("error %d copying in message segment\n", eval));
|
||||
MSG_PRINTF(("error %d copying in message segment\n",
|
||||
error));
|
||||
msg_freehdr(msghdr);
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
wakeup(msqptr);
|
||||
return (error);
|
||||
}
|
||||
msgsz -= tlen;
|
||||
user_msgp += tlen;
|
||||
@ -586,13 +640,13 @@ sys_msgsnd(p, v, retval)
|
||||
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
wakeup(msqptr);
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
return (EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code yet! */
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -600,23 +654,22 @@ sys_msgsnd(p, v, retval)
|
||||
* Put the message into the queue
|
||||
*/
|
||||
|
||||
if (msqptr->msg_first == NULL) {
|
||||
msqptr->msg_first = msghdr;
|
||||
msqptr->msg_last = msghdr;
|
||||
if (msqptr->_msg_first == NULL) {
|
||||
msqptr->_msg_first = msghdr;
|
||||
msqptr->_msg_last = msghdr;
|
||||
} else {
|
||||
msqptr->msg_last->msg_next = msghdr;
|
||||
msqptr->msg_last = msghdr;
|
||||
msqptr->_msg_last->msg_next = msghdr;
|
||||
msqptr->_msg_last = msghdr;
|
||||
}
|
||||
msqptr->msg_last->msg_next = NULL;
|
||||
msqptr->_msg_last->msg_next = NULL;
|
||||
|
||||
msqptr->msg_cbytes += msghdr->msg_ts;
|
||||
msqptr->_msg_cbytes += msghdr->msg_ts;
|
||||
msqptr->msg_qnum++;
|
||||
msqptr->msg_lspid = p->p_pid;
|
||||
msqptr->msg_stime = time.tv_sec;
|
||||
|
||||
wakeup((caddr_t)msqptr);
|
||||
*retval = 0;
|
||||
return(0);
|
||||
wakeup(msqptr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -640,8 +693,8 @@ sys_msgrcv(p, v, retval)
|
||||
size_t len;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
register struct msqid_ds *msqptr;
|
||||
register struct msg *msghdr;
|
||||
int eval;
|
||||
register struct __msg *msghdr;
|
||||
int error;
|
||||
short next;
|
||||
|
||||
MSG_PRINTF(("call to msgrcv(%d, %p, %d, %ld, %d)\n", msqid, user_msgp,
|
||||
@ -652,57 +705,60 @@ sys_msgrcv(p, v, retval)
|
||||
if (msqid < 0 || msqid >= msginfo.msgmni) {
|
||||
MSG_PRINTF(("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
MSG_PRINTF(("no such message queue id\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
if (msqptr->msg_perm._seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
MSG_PRINTF(("wrong sequence number\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if ((eval = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
|
||||
if ((error = ipcperm(cred, &msqptr->msg_perm, IPC_R))) {
|
||||
MSG_PRINTF(("requester doesn't have read access\n"));
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* cannot happen, msgsz is unsigned */
|
||||
if (msgsz < 0) {
|
||||
MSG_PRINTF(("msgsz < 0\n"));
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
msghdr = NULL;
|
||||
while (msghdr == NULL) {
|
||||
if (msgtyp == 0) {
|
||||
msghdr = msqptr->msg_first;
|
||||
msghdr = msqptr->_msg_first;
|
||||
if (msghdr != NULL) {
|
||||
if (msgsz < msghdr->msg_ts &&
|
||||
(msgflg & MSG_NOERROR) == 0) {
|
||||
MSG_PRINTF(("first message on the queue is too big (want %d, got %d)\n",
|
||||
MSG_PRINTF(("first message on the "
|
||||
"queue is too big "
|
||||
"(want %d, got %d)\n",
|
||||
msgsz, msghdr->msg_ts));
|
||||
return(E2BIG);
|
||||
return (E2BIG);
|
||||
}
|
||||
if (msqptr->msg_first == msqptr->msg_last) {
|
||||
msqptr->msg_first = NULL;
|
||||
msqptr->msg_last = NULL;
|
||||
if (msqptr->_msg_first == msqptr->_msg_last) {
|
||||
msqptr->_msg_first = NULL;
|
||||
msqptr->_msg_last = NULL;
|
||||
} else {
|
||||
msqptr->msg_first = msghdr->msg_next;
|
||||
if (msqptr->msg_first == NULL)
|
||||
panic("msg_first/last screwed up #1");
|
||||
msqptr->_msg_first = msghdr->msg_next;
|
||||
if (msqptr->_msg_first == NULL)
|
||||
panic("msg_first/last screwed "
|
||||
"up #1");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct msg *previous;
|
||||
struct msg **prev;
|
||||
struct __msg *previous;
|
||||
struct __msg **prev;
|
||||
|
||||
for (previous = NULL, prev = &msqptr->msg_first;
|
||||
for (previous = NULL, prev = &msqptr->_msg_first;
|
||||
(msghdr = *prev) != NULL;
|
||||
previous = msghdr, prev = &msghdr->msg_next) {
|
||||
/*
|
||||
@ -716,29 +772,32 @@ sys_msgrcv(p, v, retval)
|
||||
|
||||
if (msgtyp == msghdr->msg_type ||
|
||||
msghdr->msg_type <= -msgtyp) {
|
||||
MSG_PRINTF(("found message type %d, requested %d\n",
|
||||
MSG_PRINTF(("found message type %d, "
|
||||
"requested %d\n",
|
||||
msghdr->msg_type, msgtyp));
|
||||
if (msgsz < msghdr->msg_ts &&
|
||||
(msgflg & MSG_NOERROR) == 0) {
|
||||
MSG_PRINTF(("requested message on the queue is too big (want %d, got %d)\n",
|
||||
MSG_PRINTF(("requested message "
|
||||
"on the queue is too big "
|
||||
"(want %d, got %d)\n",
|
||||
msgsz, msghdr->msg_ts));
|
||||
return(E2BIG);
|
||||
return (E2BIG);
|
||||
}
|
||||
*prev = msghdr->msg_next;
|
||||
if (msghdr == msqptr->msg_last) {
|
||||
if (msghdr == msqptr->_msg_last) {
|
||||
if (previous == NULL) {
|
||||
if (prev !=
|
||||
&msqptr->msg_first)
|
||||
&msqptr->_msg_first)
|
||||
panic("msg_first/last screwed up #2");
|
||||
msqptr->msg_first =
|
||||
msqptr->_msg_first =
|
||||
NULL;
|
||||
msqptr->msg_last =
|
||||
msqptr->_msg_last =
|
||||
NULL;
|
||||
} else {
|
||||
if (prev ==
|
||||
&msqptr->msg_first)
|
||||
&msqptr->_msg_first)
|
||||
panic("msg_first/last screwed up #3");
|
||||
msqptr->msg_last =
|
||||
msqptr->_msg_last =
|
||||
previous;
|
||||
}
|
||||
}
|
||||
@ -765,10 +824,10 @@ sys_msgrcv(p, v, retval)
|
||||
msgtyp));
|
||||
/* The SVID says to return ENOMSG. */
|
||||
#ifdef ENOMSG
|
||||
return(ENOMSG);
|
||||
return (ENOMSG);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code yet! */
|
||||
return(EAGAIN);
|
||||
return (EAGAIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -777,13 +836,13 @@ sys_msgrcv(p, v, retval)
|
||||
*/
|
||||
|
||||
MSG_PRINTF(("msgrcv: goodnight\n"));
|
||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
||||
error = tsleep(msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
||||
0);
|
||||
MSG_PRINTF(("msgrcv: good morning (eval=%d)\n", eval));
|
||||
MSG_PRINTF(("msgrcv: good morning (error=%d)\n", error));
|
||||
|
||||
if (eval != 0) {
|
||||
MSG_PRINTF(("msgsnd: interrupted system call\n"));
|
||||
return(EINTR);
|
||||
if (error != 0) {
|
||||
MSG_PRINTF(("msgsnd: interrupted system call\n"));
|
||||
return (EINTR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -791,14 +850,14 @@ sys_msgrcv(p, v, retval)
|
||||
*/
|
||||
|
||||
if (msqptr->msg_qbytes == 0 ||
|
||||
msqptr->msg_perm.seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
msqptr->msg_perm._seq != IPCID_TO_SEQ(SCARG(uap, msqid))) {
|
||||
MSG_PRINTF(("msqid deleted\n"));
|
||||
/* The SVID says to return EIDRM. */
|
||||
#ifdef EIDRM
|
||||
return(EIDRM);
|
||||
return (EIDRM);
|
||||
#else
|
||||
/* Unfortunately, BSD doesn't define that code yet! */
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -809,7 +868,7 @@ sys_msgrcv(p, v, retval)
|
||||
* First, do the bookkeeping (before we risk being interrupted).
|
||||
*/
|
||||
|
||||
msqptr->msg_cbytes -= msghdr->msg_ts;
|
||||
msqptr->_msg_cbytes -= msghdr->msg_ts;
|
||||
msqptr->msg_qnum--;
|
||||
msqptr->msg_lrpid = p->p_pid;
|
||||
msqptr->msg_rtime = time.tv_sec;
|
||||
@ -829,13 +888,12 @@ sys_msgrcv(p, v, retval)
|
||||
* Return the type to the user.
|
||||
*/
|
||||
|
||||
eval = copyout((caddr_t)&msghdr->msg_type, user_msgp,
|
||||
sizeof(msghdr->msg_type));
|
||||
if (eval != 0) {
|
||||
MSG_PRINTF(("error (%d) copying out message type\n", eval));
|
||||
error = copyout(&msghdr->msg_type, user_msgp, sizeof(msghdr->msg_type));
|
||||
if (error != 0) {
|
||||
MSG_PRINTF(("error (%d) copying out message type\n", error));
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
wakeup(msqptr);
|
||||
return (error);
|
||||
}
|
||||
user_msgp += sizeof(msghdr->msg_type);
|
||||
|
||||
@ -855,14 +913,14 @@ sys_msgrcv(p, v, retval)
|
||||
panic("next too low #3");
|
||||
if (next >= msginfo.msgseg)
|
||||
panic("next out of range #3");
|
||||
eval = copyout((caddr_t)&msgpool[next * msginfo.msgssz],
|
||||
error = copyout(&msgpool[next * msginfo.msgssz],
|
||||
user_msgp, tlen);
|
||||
if (eval != 0) {
|
||||
if (error != 0) {
|
||||
MSG_PRINTF(("error (%d) copying out message segment\n",
|
||||
eval));
|
||||
error));
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
wakeup(msqptr);
|
||||
return (error);
|
||||
}
|
||||
user_msgp += tlen;
|
||||
next = msgmaps[next].next;
|
||||
@ -873,7 +931,7 @@ sys_msgrcv(p, v, retval)
|
||||
*/
|
||||
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
wakeup(msqptr);
|
||||
*retval = msgsz;
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,9 +1,46 @@
|
||||
/* $NetBSD: sysv_sem.c,v 1.32 1998/10/21 22:24:28 tron Exp $ */
|
||||
/* $NetBSD: sysv_sem.c,v 1.33 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implementation of SVID semaphores
|
||||
*
|
||||
* Author: Daniel Boulet
|
||||
* Author: Daniel Boulet
|
||||
*
|
||||
* This software is provided ``AS IS'' without any warranties of any kind.
|
||||
*/
|
||||
@ -45,7 +82,7 @@ seminit()
|
||||
panic("semu is NULL");
|
||||
|
||||
for (i = 0; i < seminfo.semmni; i++) {
|
||||
sema[i].sem_base = 0;
|
||||
sema[i]._sem_base = 0;
|
||||
sema[i].sem_perm.mode = 0;
|
||||
}
|
||||
for (i = 0; i < seminfo.semmnu; i++) {
|
||||
@ -285,167 +322,184 @@ semundo_clear(semid, semnum)
|
||||
}
|
||||
|
||||
int
|
||||
sys___semctl(p, v, retval)
|
||||
sys___semctl13(p, v, retval)
|
||||
struct proc *p;
|
||||
register void *v;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
register struct sys___semctl_args /* {
|
||||
struct sys___semctl13_args /* {
|
||||
syscallarg(int) semid;
|
||||
syscallarg(int) semnum;
|
||||
syscallarg(int) cmd;
|
||||
syscallarg(union semun *) arg;
|
||||
syscallarg(union __semun) arg;
|
||||
} */ *uap = v;
|
||||
int semid = SCARG(uap, semid);
|
||||
int semnum = SCARG(uap, semnum);
|
||||
int cmd = SCARG(uap, cmd);
|
||||
union semun *arg = SCARG(uap, arg);
|
||||
union semun real_arg;
|
||||
struct semid_ds sembuf;
|
||||
int cmd, error;
|
||||
void *pass_arg = NULL;
|
||||
|
||||
cmd = SCARG(uap, cmd);
|
||||
|
||||
switch (cmd) {
|
||||
case IPC_SET:
|
||||
case IPC_STAT:
|
||||
pass_arg = &sembuf;
|
||||
break;
|
||||
|
||||
case GETALL:
|
||||
case SETVAL:
|
||||
case SETALL:
|
||||
pass_arg = &SCARG(uap, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd == IPC_SET) {
|
||||
error = copyin(SCARG(uap, arg).buf, &sembuf, sizeof(sembuf));
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum), cmd,
|
||||
pass_arg, retval);
|
||||
|
||||
if (error == 0 && cmd == IPC_STAT)
|
||||
error = copyout(&sembuf, SCARG(uap, arg).buf, sizeof(sembuf));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
semctl1(p, semid, semnum, cmd, v, retval)
|
||||
struct proc *p;
|
||||
int semid, semnum, cmd;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
struct ucred *cred = p->p_ucred;
|
||||
int i, rval, eval;
|
||||
struct semid_ds sbuf;
|
||||
register struct semid_ds *semaptr;
|
||||
union __semun *arg = v;
|
||||
struct semid_ds *sembuf = v, *semaptr;
|
||||
int i, error, ix;
|
||||
|
||||
SEM_PRINTF(("call to semctl(%d, %d, %d, %p)\n",
|
||||
semid, semnum, cmd, arg));
|
||||
semid, semnum, cmd, v));
|
||||
|
||||
semlock(p);
|
||||
|
||||
semid = IPCID_TO_IX(semid);
|
||||
if (semid < 0 || semid >= seminfo.semmsl)
|
||||
return(EINVAL);
|
||||
ix = IPCID_TO_IX(semid);
|
||||
if (ix < 0 || ix >= seminfo.semmsl)
|
||||
return (EINVAL);
|
||||
|
||||
semaptr = &sema[semid];
|
||||
semaptr = &sema[ix];
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
|
||||
return(EINVAL);
|
||||
|
||||
eval = 0;
|
||||
rval = 0;
|
||||
semaptr->sem_perm._seq != IPCID_TO_SEQ(semid))
|
||||
return (EINVAL);
|
||||
|
||||
switch (cmd) {
|
||||
case IPC_RMID:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)) != 0)
|
||||
return (error);
|
||||
semaptr->sem_perm.cuid = cred->cr_uid;
|
||||
semaptr->sem_perm.uid = cred->cr_uid;
|
||||
semtot -= semaptr->sem_nsems;
|
||||
for (i = semaptr->sem_base - sem; i < semtot; i++)
|
||||
for (i = semaptr->_sem_base - sem; i < semtot; i++)
|
||||
sem[i] = sem[i + semaptr->sem_nsems];
|
||||
for (i = 0; i < seminfo.semmni; i++) {
|
||||
if ((sema[i].sem_perm.mode & SEM_ALLOC) &&
|
||||
sema[i].sem_base > semaptr->sem_base)
|
||||
sema[i].sem_base -= semaptr->sem_nsems;
|
||||
sema[i]._sem_base > semaptr->_sem_base)
|
||||
sema[i]._sem_base -= semaptr->sem_nsems;
|
||||
}
|
||||
semaptr->sem_perm.mode = 0;
|
||||
semundo_clear(semid, -1);
|
||||
wakeup((caddr_t)semaptr);
|
||||
semundo_clear(ix, -1);
|
||||
wakeup(semaptr);
|
||||
break;
|
||||
|
||||
case IPC_SET:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((eval = copyin(real_arg.buf, (caddr_t)&sbuf,
|
||||
sizeof(sbuf))) != 0)
|
||||
return(eval);
|
||||
semaptr->sem_perm.uid = sbuf.sem_perm.uid;
|
||||
semaptr->sem_perm.gid = sbuf.sem_perm.gid;
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_M)))
|
||||
return (error);
|
||||
semaptr->sem_perm.uid = sembuf->sem_perm.uid;
|
||||
semaptr->sem_perm.gid = sembuf->sem_perm.gid;
|
||||
semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
|
||||
(sbuf.sem_perm.mode & 0777);
|
||||
(sembuf->sem_perm.mode & 0777);
|
||||
semaptr->sem_ctime = time.tv_sec;
|
||||
break;
|
||||
|
||||
case IPC_STAT:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
eval = copyout((caddr_t)semaptr, real_arg.buf,
|
||||
sizeof(struct semid_ds));
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
memcpy(sembuf, semaptr, sizeof(struct semid_ds));
|
||||
break;
|
||||
|
||||
case GETNCNT:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
rval = semaptr->sem_base[semnum].semncnt;
|
||||
return (EINVAL);
|
||||
*retval = semaptr->_sem_base[semnum].semncnt;
|
||||
break;
|
||||
|
||||
case GETPID:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
rval = semaptr->sem_base[semnum].sempid;
|
||||
return (EINVAL);
|
||||
*retval = semaptr->_sem_base[semnum].sempid;
|
||||
break;
|
||||
|
||||
case GETVAL:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
rval = semaptr->sem_base[semnum].semval;
|
||||
return (EINVAL);
|
||||
*retval = semaptr->_sem_base[semnum].semval;
|
||||
break;
|
||||
|
||||
case GETALL:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||
eval = copyout((caddr_t)&semaptr->sem_base[i].semval,
|
||||
&real_arg.array[i], sizeof(real_arg.array[0]));
|
||||
if (eval != 0)
|
||||
error = copyout(&semaptr->_sem_base[i].semval,
|
||||
&arg->array[i], sizeof(arg->array[i]));
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GETZCNT:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_R)))
|
||||
return (error);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
rval = semaptr->sem_base[semnum].semzcnt;
|
||||
return (EINVAL);
|
||||
*retval = semaptr->_sem_base[semnum].semzcnt;
|
||||
break;
|
||||
|
||||
case SETVAL:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
|
||||
return (error);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
semaptr->sem_base[semnum].semval = real_arg.val;
|
||||
semundo_clear(semid, semnum);
|
||||
wakeup((caddr_t)semaptr);
|
||||
return (EINVAL);
|
||||
semaptr->_sem_base[semnum].semval = arg->val;
|
||||
semundo_clear(ix, semnum);
|
||||
wakeup(semaptr);
|
||||
break;
|
||||
|
||||
case SETALL:
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(cred, &semaptr->sem_perm, IPC_W)))
|
||||
return (error);
|
||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||
eval = copyin(&real_arg.array[i],
|
||||
(caddr_t)&semaptr->sem_base[i].semval,
|
||||
sizeof(real_arg.array[0]));
|
||||
if (eval != 0)
|
||||
error = copyin(&arg->array[i],
|
||||
&semaptr->_sem_base[i].semval,
|
||||
sizeof(arg->array[i]));
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
semundo_clear(semid, -1);
|
||||
wakeup((caddr_t)semaptr);
|
||||
semundo_clear(ix, -1);
|
||||
wakeup(semaptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
return(EINVAL);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if (eval == 0)
|
||||
*retval = rval;
|
||||
return(eval);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
@ -472,7 +526,7 @@ sys_semget(p, v, retval)
|
||||
if (key != IPC_PRIVATE) {
|
||||
for (semid = 0; semid < seminfo.semmni; semid++) {
|
||||
if ((sema[semid].sem_perm.mode & SEM_ALLOC) &&
|
||||
sema[semid].sem_perm.key == key)
|
||||
sema[semid].sem_perm._key == key)
|
||||
break;
|
||||
}
|
||||
if (semid < seminfo.semmni) {
|
||||
@ -513,22 +567,22 @@ sys_semget(p, v, retval)
|
||||
return(ENOSPC);
|
||||
}
|
||||
SEM_PRINTF(("semid %d is available\n", semid));
|
||||
sema[semid].sem_perm.key = key;
|
||||
sema[semid].sem_perm._key = key;
|
||||
sema[semid].sem_perm.cuid = cred->cr_uid;
|
||||
sema[semid].sem_perm.uid = cred->cr_uid;
|
||||
sema[semid].sem_perm.cgid = cred->cr_gid;
|
||||
sema[semid].sem_perm.gid = cred->cr_gid;
|
||||
sema[semid].sem_perm.mode = (semflg & 0777) | SEM_ALLOC;
|
||||
sema[semid].sem_perm.seq =
|
||||
(sema[semid].sem_perm.seq + 1) & 0x7fff;
|
||||
sema[semid].sem_perm._seq =
|
||||
(sema[semid].sem_perm._seq + 1) & 0x7fff;
|
||||
sema[semid].sem_nsems = nsems;
|
||||
sema[semid].sem_otime = 0;
|
||||
sema[semid].sem_ctime = time.tv_sec;
|
||||
sema[semid].sem_base = &sem[semtot];
|
||||
sema[semid]._sem_base = &sem[semtot];
|
||||
semtot += nsems;
|
||||
memset(sema[semid].sem_base, 0,
|
||||
sizeof(sema[semid].sem_base[0])*nsems);
|
||||
SEM_PRINTF(("sembase = %p, next = %p\n", sema[semid].sem_base,
|
||||
memset(sema[semid]._sem_base, 0,
|
||||
sizeof(sema[semid]._sem_base[0])*nsems);
|
||||
SEM_PRINTF(("sembase = %p, next = %p\n", sema[semid]._sem_base,
|
||||
&sem[semtot]));
|
||||
} else {
|
||||
SEM_PRINTF(("didn't find it and wasn't asked to create it\n"));
|
||||
@ -556,7 +610,7 @@ sys_semop(p, v, retval)
|
||||
struct sembuf sops[MAX_SOPS];
|
||||
register struct semid_ds *semaptr;
|
||||
register struct sembuf *sopptr = NULL;
|
||||
register struct sem *semptr = NULL;
|
||||
register struct __sem *semptr = NULL;
|
||||
struct sem_undo *suptr = NULL;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
int i, j, eval;
|
||||
@ -573,7 +627,7 @@ sys_semop(p, v, retval)
|
||||
|
||||
semaptr = &sema[semid];
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid)))
|
||||
semaptr->sem_perm._seq != IPCID_TO_SEQ(SCARG(uap, semid)))
|
||||
return(EINVAL);
|
||||
|
||||
if ((eval = ipcperm(cred, &semaptr->sem_perm, IPC_W))) {
|
||||
@ -613,10 +667,10 @@ sys_semop(p, v, retval)
|
||||
if (sopptr->sem_num >= semaptr->sem_nsems)
|
||||
return(EFBIG);
|
||||
|
||||
semptr = &semaptr->sem_base[sopptr->sem_num];
|
||||
semptr = &semaptr->_sem_base[sopptr->sem_num];
|
||||
|
||||
SEM_PRINTF(("semop: semaptr=%x, sem_base=%x, semptr=%x, sem[%d]=%d : op=%d, flag=%s\n",
|
||||
semaptr, semaptr->sem_base, semptr,
|
||||
semaptr, semaptr->_sem_base, semptr,
|
||||
sopptr->sem_num, semptr->semval, sopptr->sem_op,
|
||||
(sopptr->sem_flg & IPC_NOWAIT) ? "nowait" : "wait"));
|
||||
|
||||
@ -658,7 +712,7 @@ sys_semop(p, v, retval)
|
||||
*/
|
||||
SEM_PRINTF(("semop: rollback 0 through %d\n", i-1));
|
||||
for (j = 0; j < i; j++)
|
||||
semaptr->sem_base[sops[j].sem_num].semval -=
|
||||
semaptr->_sem_base[sops[j].sem_num].semval -=
|
||||
sops[j].sem_op;
|
||||
|
||||
/*
|
||||
@ -688,7 +742,7 @@ sys_semop(p, v, retval)
|
||||
* Make sure that the semaphore still exists
|
||||
*/
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(SCARG(uap, semid))) {
|
||||
semaptr->sem_perm._seq != IPCID_TO_SEQ(SCARG(uap, semid))) {
|
||||
/* The man page says to return EIDRM. */
|
||||
/* Unfortunately, BSD doesn't define that code! */
|
||||
#ifdef EIDRM
|
||||
@ -751,7 +805,7 @@ done:
|
||||
}
|
||||
|
||||
for (j = 0; j < nsops; j++)
|
||||
semaptr->sem_base[sops[j].sem_num].semval -=
|
||||
semaptr->_sem_base[sops[j].sem_num].semval -=
|
||||
sops[j].sem_op;
|
||||
|
||||
SEM_PRINTF(("eval = %d from semundo_adjust\n", eval));
|
||||
@ -762,7 +816,7 @@ done:
|
||||
/* We're definitely done - set the sempid's */
|
||||
for (i = 0; i < nsops; i++) {
|
||||
sopptr = &sops[i];
|
||||
semptr = &semaptr->sem_base[sopptr->sem_num];
|
||||
semptr = &semaptr->_sem_base[sopptr->sem_num];
|
||||
semptr->sempid = p->p_pid;
|
||||
}
|
||||
|
||||
@ -923,13 +977,13 @@ semexit(p)
|
||||
suptr->un_proc, suptr->un_ent[ix].un_id,
|
||||
suptr->un_ent[ix].un_num,
|
||||
suptr->un_ent[ix].un_adjval,
|
||||
semaptr->sem_base[semnum].semval));
|
||||
semaptr->_sem_base[semnum].semval));
|
||||
|
||||
if (adjval < 0 &&
|
||||
semaptr->sem_base[semnum].semval < -adjval)
|
||||
semaptr->sem_base[semnum].semval = 0;
|
||||
semaptr->_sem_base[semnum].semval < -adjval)
|
||||
semaptr->_sem_base[semnum].semval = 0;
|
||||
else
|
||||
semaptr->sem_base[semnum].semval += adjval;
|
||||
semaptr->_sem_base[semnum].semval += adjval;
|
||||
|
||||
#ifdef SEM_WAKEUP
|
||||
sem_wakeup((caddr_t)semaptr);
|
||||
|
@ -1,4 +1,41 @@
|
||||
/* $NetBSD: sysv_shm.c,v 1.51 1999/03/24 05:51:25 mrg Exp $ */
|
||||
/* $NetBSD: sysv_shm.c,v 1.52 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Adam Glass and Charles M. Hannum. All rights reserved.
|
||||
@ -58,7 +95,6 @@ struct shmid_ds *shm_find_segment_by_shmid __P((int));
|
||||
* shminit(void); initialization
|
||||
* shmexit(struct vmspace *) cleanup
|
||||
* shmfork(struct vmspace *, struct vmspace *) fork handling
|
||||
* shmsys(arg1, arg2, arg3, arg4); shm{at,ctl,dt,get}(arg2, arg3, arg4)
|
||||
*
|
||||
* Structures:
|
||||
* shmsegs (an array of 'struct shmid_ds')
|
||||
@ -97,7 +133,7 @@ shm_find_segment_by_key(key)
|
||||
|
||||
for (i = 0; i < shminfo.shmmni; i++)
|
||||
if ((shmsegs[i].shm_perm.mode & SHMSEG_ALLOCATED) &&
|
||||
shmsegs[i].shm_perm.key == key)
|
||||
shmsegs[i].shm_perm._key == key)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
@ -115,7 +151,7 @@ shm_find_segment_by_shmid(shmid)
|
||||
shmseg = &shmsegs[segnum];
|
||||
if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED))
|
||||
!= SHMSEG_ALLOCATED ||
|
||||
shmseg->shm_perm.seq != IPCID_TO_SEQ(shmid))
|
||||
shmseg->shm_perm._seq != IPCID_TO_SEQ(shmid))
|
||||
return NULL;
|
||||
return shmseg;
|
||||
}
|
||||
@ -127,11 +163,11 @@ shm_deallocate_segment(shmseg)
|
||||
struct shm_handle *shm_handle;
|
||||
size_t size;
|
||||
|
||||
shm_handle = shmseg->shm_internal;
|
||||
shm_handle = shmseg->_shm_internal;
|
||||
size = (shmseg->shm_segsz + CLOFSET) & ~CLOFSET;
|
||||
uao_detach(shm_handle->shm_object);
|
||||
free((caddr_t)shm_handle, M_SHM);
|
||||
shmseg->shm_internal = NULL;
|
||||
shmseg->_shm_internal = NULL;
|
||||
shm_committed -= btoc(size);
|
||||
shmseg->shm_perm.mode = SHMSEG_FREE;
|
||||
shm_nused--;
|
||||
@ -249,7 +285,7 @@ sys_shmat(p, v, retval)
|
||||
attach_va =
|
||||
round_page(p->p_vmspace->vm_taddr + MAXTSIZ + MAXDSIZ);
|
||||
}
|
||||
shm_handle = shmseg->shm_internal;
|
||||
shm_handle = shmseg->_shm_internal;
|
||||
uao_reference(shm_handle->shm_object);
|
||||
rv = uvm_map(&p->p_vmspace->vm_map, &attach_va, size,
|
||||
shm_handle->shm_object, 0,
|
||||
@ -269,55 +305,74 @@ sys_shmat(p, v, retval)
|
||||
}
|
||||
|
||||
int
|
||||
sys_shmctl(p, v, retval)
|
||||
sys___shmctl13(p, v, retval)
|
||||
struct proc *p;
|
||||
void *v;
|
||||
register_t *retval;
|
||||
{
|
||||
struct sys_shmctl_args /* {
|
||||
struct sys___shmctl13_args /* {
|
||||
syscallarg(int) shmid;
|
||||
syscallarg(int) cmd;
|
||||
syscallarg(struct shmid_ds *) buf;
|
||||
} */ *uap = v;
|
||||
int error;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
struct shmid_ds inbuf;
|
||||
struct shmid_ds *shmseg;
|
||||
} */ *uap = v;
|
||||
struct shmid_ds shmbuf;
|
||||
int cmd, error;
|
||||
|
||||
shmseg = shm_find_segment_by_shmid(SCARG(uap, shmid));
|
||||
cmd = SCARG(uap, cmd);
|
||||
|
||||
if (cmd == IPC_SET) {
|
||||
error = copyin(SCARG(uap, buf), &shmbuf, sizeof(shmbuf));
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = shmctl1(p, SCARG(uap, shmid), cmd,
|
||||
(cmd == IPC_SET || cmd == IPC_STAT) ? &shmbuf : NULL);
|
||||
|
||||
if (error == 0 && cmd == IPC_STAT)
|
||||
error = copyout(&shmbuf, SCARG(uap, buf), sizeof(shmbuf));
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
shmctl1(p, shmid, cmd, shmbuf)
|
||||
struct proc *p;
|
||||
int shmid;
|
||||
int cmd;
|
||||
struct shmid_ds *shmbuf;
|
||||
{
|
||||
struct ucred *cred = p->p_ucred;
|
||||
struct shmid_ds *shmseg;
|
||||
int error = 0;
|
||||
|
||||
shmseg = shm_find_segment_by_shmid(shmid);
|
||||
if (shmseg == NULL)
|
||||
return EINVAL;
|
||||
switch (SCARG(uap, cmd)) {
|
||||
switch (cmd) {
|
||||
case IPC_STAT:
|
||||
if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_R)) != 0)
|
||||
return error;
|
||||
error = copyout((caddr_t)shmseg, SCARG(uap, buf),
|
||||
sizeof(inbuf));
|
||||
if (error)
|
||||
return error;
|
||||
memcpy(shmbuf, shmseg, sizeof(struct shmid_ds));
|
||||
break;
|
||||
case IPC_SET:
|
||||
if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0)
|
||||
return error;
|
||||
error = copyin(SCARG(uap, buf), (caddr_t)&inbuf,
|
||||
sizeof(inbuf));
|
||||
if (error)
|
||||
return error;
|
||||
shmseg->shm_perm.uid = inbuf.shm_perm.uid;
|
||||
shmseg->shm_perm.gid = inbuf.shm_perm.gid;
|
||||
shmseg->shm_perm.uid = shmbuf->shm_perm.uid;
|
||||
shmseg->shm_perm.gid = shmbuf->shm_perm.gid;
|
||||
shmseg->shm_perm.mode =
|
||||
(shmseg->shm_perm.mode & ~ACCESSPERMS) |
|
||||
(inbuf.shm_perm.mode & ACCESSPERMS);
|
||||
(shmbuf->shm_perm.mode & ACCESSPERMS);
|
||||
shmseg->shm_ctime = time.tv_sec;
|
||||
break;
|
||||
case IPC_RMID:
|
||||
if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0)
|
||||
return error;
|
||||
shmseg->shm_perm.key = IPC_PRIVATE;
|
||||
shmseg->shm_perm._key = IPC_PRIVATE;
|
||||
shmseg->shm_perm.mode |= SHMSEG_REMOVED;
|
||||
if (shmseg->shm_nattch <= 0) {
|
||||
shm_deallocate_segment(shmseg);
|
||||
shm_last_free = IPCID_TO_IX(SCARG(uap, shmid));
|
||||
shm_last_free = IPCID_TO_IX(shmid);
|
||||
}
|
||||
break;
|
||||
case SHM_LOCK:
|
||||
@ -410,15 +465,15 @@ shmget_allocate_segment(p, uap, mode, retval)
|
||||
* so that noone else tries to create the same key.
|
||||
*/
|
||||
shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
|
||||
shmseg->shm_perm.key = SCARG(uap, key);
|
||||
shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff;
|
||||
shmseg->shm_perm._key = SCARG(uap, key);
|
||||
shmseg->shm_perm._seq = (shmseg->shm_perm._seq + 1) & 0x7fff;
|
||||
shm_handle = (struct shm_handle *)
|
||||
malloc(sizeof(struct shm_handle), M_SHM, M_WAITOK);
|
||||
shmid = IXSEQ_TO_IPCID(segnum, shmseg->shm_perm);
|
||||
|
||||
shm_handle->shm_object = uao_create(size, 0);
|
||||
|
||||
shmseg->shm_internal = shm_handle;
|
||||
shmseg->_shm_internal = shm_handle;
|
||||
shmseg->shm_perm.cuid = shmseg->shm_perm.uid = cred->cr_uid;
|
||||
shmseg->shm_perm.cgid = shmseg->shm_perm.gid = cred->cr_gid;
|
||||
shmseg->shm_perm.mode = (shmseg->shm_perm.mode & SHMSEG_WANTED) |
|
||||
@ -520,7 +575,7 @@ shminit()
|
||||
|
||||
for (i = 0; i < shminfo.shmmni; i++) {
|
||||
shmsegs[i].shm_perm.mode = SHMSEG_FREE;
|
||||
shmsegs[i].shm_perm.seq = 0;
|
||||
shmsegs[i].shm_perm._seq = 0;
|
||||
}
|
||||
shm_last_free = 0;
|
||||
shm_nused = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ipc.h,v 1.20 1999/04/17 21:00:09 kleink Exp $ */
|
||||
/* $NetBSD: ipc.h,v 1.21 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
@ -52,15 +52,37 @@
|
||||
#define _SYS_IPC_H_
|
||||
|
||||
struct ipc_perm {
|
||||
uid_t uid; /* user id */
|
||||
gid_t gid; /* group id */
|
||||
uid_t cuid; /* creator user id */
|
||||
gid_t cgid; /* creator group id */
|
||||
mode_t mode; /* r/w permission */
|
||||
|
||||
/*
|
||||
* These members are private and used only in the internal
|
||||
* implementation of this interface.
|
||||
*/
|
||||
unsigned short _seq; /* sequence # (to generate unique
|
||||
msg/sem/shm id) */
|
||||
key_t _key; /* user specified msg/sem/shm key */
|
||||
};
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Old IPC permission structure used before NetBSD 1.5.
|
||||
*/
|
||||
struct ipc_perm14 {
|
||||
unsigned short cuid; /* creator user id */
|
||||
unsigned short cgid; /* creator group id */
|
||||
unsigned short uid; /* user id */
|
||||
unsigned short gid; /* group id */
|
||||
unsigned short mode; /* r/w permission */
|
||||
unsigned short seq; /* sequence # (to generate unique msg/sem/shm
|
||||
id) */
|
||||
unsigned short seq; /* sequence # (to generate unique
|
||||
msg/sem/shm id) */
|
||||
key_t key; /* user specified msg/sem/shm key */
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* X/Open required constants (same values as system 5) */
|
||||
#define IPC_CREAT 001000 /* create entry if key does not exist */
|
||||
@ -77,14 +99,17 @@ struct ipc_perm {
|
||||
/* Macros to convert between ipc ids and array indices or sequence ids */
|
||||
#define IPCID_TO_IX(id) ((id) & 0xffff)
|
||||
#define IPCID_TO_SEQ(id) (((id) >> 16) & 0xffff)
|
||||
#define IXSEQ_TO_IPCID(ix,perm) (((perm.seq) << 16) | (ix & 0xffff))
|
||||
#define IXSEQ_TO_IPCID(ix,perm) (((perm._seq) << 16) | (ix & 0xffff))
|
||||
|
||||
/* Common access type bits, used with ipcperm(). */
|
||||
#define IPC_R 000400 /* read permission */
|
||||
#define IPC_W 000200 /* write/alter permission */
|
||||
#define IPC_M 010000 /* permission to change control info */
|
||||
|
||||
int ipcperm __P((struct ucred *, struct ipc_perm *, int));
|
||||
int ipcperm __P((struct ucred *, struct ipc_perm *, int));
|
||||
|
||||
void ipc_perm14_to_native __P((struct ipc_perm14 *, struct ipc_perm *));
|
||||
void native_to_ipc_perm14 __P((struct ipc_perm *, struct ipc_perm14 *));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
138
sys/sys/msg.h
138
sys/sys/msg.h
@ -1,4 +1,41 @@
|
||||
/* $NetBSD: msg.h,v 1.10 1998/05/07 16:41:08 kleink Exp $ */
|
||||
/* $NetBSD: msg.h,v 1.11 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SVID compatible msg.h file
|
||||
@ -24,17 +61,49 @@
|
||||
|
||||
#include <sys/ipc.h>
|
||||
|
||||
/*
|
||||
* The MSG_NOERROR identifier value, the msqid_ds struct and the msg struct
|
||||
* are as defined by the SV API Intel 386 Processor Supplement.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
struct __msg {
|
||||
struct __msg *msg_next; /* next msg in the chain */
|
||||
long msg_type; /* type of this message */
|
||||
/* >0 -> type of this message */
|
||||
/* 0 -> free header */
|
||||
u_short msg_ts; /* size of this message */
|
||||
short msg_spot; /* location of start of msg in buffer */
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#define MSG_NOERROR 010000 /* don't complain about too long msgs */
|
||||
|
||||
typedef unsigned long msgqnum_t;
|
||||
typedef size_t msglen_t;
|
||||
|
||||
struct msqid_ds {
|
||||
struct ipc_perm msg_perm; /* msg queue permission bits */
|
||||
struct msg *msg_first; /* first message in the queue */
|
||||
struct msg *msg_last; /* last message in the queue */
|
||||
struct ipc_perm msg_perm; /* operation permission strucure */
|
||||
msgqnum_t msg_qnum; /* number of messages in the queue */
|
||||
msglen_t msg_qbytes; /* max # of bytes in the queue */
|
||||
pid_t msg_lspid; /* process ID of last msgsend() */
|
||||
pid_t msg_lrpid; /* process ID of last msgrcv() */
|
||||
time_t msg_stime; /* time of last msgsend() */
|
||||
time_t msg_rtime; /* time of last msgrcv() */
|
||||
time_t msg_ctime; /* time of last change */
|
||||
|
||||
/*
|
||||
* These members are private and used only in the internal
|
||||
* implementation of this interface.
|
||||
*/
|
||||
struct __msg *_msg_first; /* first message in the queue */
|
||||
struct __msg *_msg_last; /* last message in the queue */
|
||||
msglen_t _msg_cbytes; /* # of bytes currently in queue */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Old message queue data structure used before NetBSD 1.5.
|
||||
*/
|
||||
struct msqid_ds14 {
|
||||
struct ipc_perm14 msg_perm; /* msg queue permission bits */
|
||||
struct __msg *msg_first; /* first message in the queue */
|
||||
struct __msg *msg_last; /* last message in the queue */
|
||||
u_long msg_cbytes; /* number of bytes in use on the queue */
|
||||
u_long msg_qnum; /* number of msgs in the queue */
|
||||
u_long msg_qbytes; /* max # of bytes on the queue */
|
||||
@ -49,32 +118,6 @@ struct msqid_ds {
|
||||
long msg_pad4[4];
|
||||
};
|
||||
|
||||
struct msg {
|
||||
struct msg *msg_next; /* next msg in the chain */
|
||||
long msg_type; /* type of this message */
|
||||
/* >0 -> type of this message */
|
||||
/* 0 -> free header */
|
||||
u_short msg_ts; /* size of this message */
|
||||
short msg_spot; /* location of start of msg in buffer */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure describing a message. The SVID doesn't suggest any
|
||||
* particular name for this structure. There is a reference in the
|
||||
* msgop man page that reads "The structure mymsg is an example of what
|
||||
* this user defined buffer might look like, and includes the following
|
||||
* members:". This sentence is followed by two lines equivalent
|
||||
* to the mtype and mtext field declarations below. It isn't clear
|
||||
* if "mymsg" refers to the naem of the structure type or the name of an
|
||||
* instance of the structure...
|
||||
*/
|
||||
struct mymsg {
|
||||
long mtype; /* message type (+ve integer) */
|
||||
char mtext[1]; /* message body */
|
||||
};
|
||||
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Based on the configuration parameters described in an SVR2 (yes, two)
|
||||
* config(1m) man page.
|
||||
@ -90,7 +133,8 @@ struct msginfo {
|
||||
msgmni, /* max message queue identifiers */
|
||||
msgmnb, /* max chars in a queue */
|
||||
msgtql, /* max messages in system */
|
||||
msgssz, /* size of a message segment (see notes above) */
|
||||
msgssz, /* size of a message segment
|
||||
(see notes above) */
|
||||
msgseg; /* number of message segments */
|
||||
};
|
||||
struct msginfo msginfo;
|
||||
@ -115,18 +159,10 @@ struct msginfo msginfo;
|
||||
|
||||
/*
|
||||
* macros to convert between msqid_ds's and msqid's.
|
||||
* (specific to this implementation)
|
||||
*/
|
||||
#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm.seq << 16) & 0xffff0000))
|
||||
#define MSQID(ix,ds) ((ix) & 0xffff | (((ds).msg_perm._seq << 16) & 0xffff0000))
|
||||
#define MSQID_IX(id) ((id) & 0xffff)
|
||||
#define MSQID_SEQ(id) (((id) >> 16) & 0xffff)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The rest of this file is specific to this particular implementation.
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* Stuff allocated in machdep.h
|
||||
@ -139,24 +175,30 @@ struct msgmap {
|
||||
|
||||
char *msgpool; /* MSGMAX byte long msg buffer pool */
|
||||
struct msgmap *msgmaps; /* MSGSEG msgmap structures */
|
||||
struct msg *msghdrs; /* MSGTQL msg headers */
|
||||
struct __msg *msghdrs; /* MSGTQL msg headers */
|
||||
struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */
|
||||
|
||||
#define MSG_LOCKED 01000 /* Is this msqid_ds locked? */
|
||||
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int msgctl __P((int, int, struct msqid_ds *));
|
||||
int msgctl __P((int, int, struct msqid_ds *)) __RENAME(__msgctl13);
|
||||
int msgget __P((key_t, int));
|
||||
int msgsnd __P((int, const void *, size_t, int));
|
||||
ssize_t msgrcv __P((int, void *, size_t, long, int));
|
||||
__END_DECLS
|
||||
#else
|
||||
void msginit __P((void));
|
||||
struct proc;
|
||||
|
||||
void msginit __P((void));
|
||||
int msgctl1 __P((struct proc *, int, int, struct msqid_ds *));
|
||||
|
||||
void msqid_ds14_to_native __P((struct msqid_ds14 *, struct msqid_ds *));
|
||||
void native_to_msqid_ds14 __P((struct msqid_ds *, struct msqid_ds14 *));
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* !_SYS_MSG_H_ */
|
||||
|
@ -1,9 +1,46 @@
|
||||
/* $NetBSD: sem.h,v 1.9 1998/05/07 16:50:21 kleink Exp $ */
|
||||
/* $NetBSD: sem.h,v 1.10 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SVID compatible sem.h file
|
||||
*
|
||||
* Author: Daniel Boulet
|
||||
* Author: Daniel Boulet
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SEM_H_
|
||||
@ -13,16 +50,32 @@
|
||||
|
||||
#include <sys/ipc.h>
|
||||
|
||||
struct sem {
|
||||
#ifdef _KERNEL
|
||||
struct __sem {
|
||||
unsigned short semval; /* semaphore value */
|
||||
pid_t sempid; /* pid of last operation */
|
||||
unsigned short semncnt; /* # awaiting semval > cval */
|
||||
unsigned short semzcnt; /* # awaiting semval = 0 */
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm; /* operation permission struct */
|
||||
struct sem *sem_base; /* pointer to first semaphore in set */
|
||||
struct ipc_perm sem_perm; /* operation permission structure */
|
||||
unsigned short sem_nsems; /* number of semaphores in set */
|
||||
time_t sem_otime; /* last semop() time */
|
||||
time_t sem_ctime; /* last time changed by semctl() */
|
||||
|
||||
/*
|
||||
* These members are private and used only in the internal
|
||||
* implementation of this interface.
|
||||
*/
|
||||
struct __sem *_sem_base; /* pointer to first semaphore in set */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct semid_ds14 {
|
||||
struct ipc_perm14 sem_perm; /* operation permission struct */
|
||||
struct __sem *sem_base; /* pointer to first semaphore in set */
|
||||
unsigned short sem_nsems; /* number of sems in set */
|
||||
time_t sem_otime; /* last operation time */
|
||||
long sem_pad1; /* SVABI/386 says I need this here */
|
||||
@ -32,6 +85,7 @@ struct semid_ds {
|
||||
long sem_pad2; /* SVABI/386 says I need this here */
|
||||
long sem_pad3[4]; /* SVABI/386 says I need this here */
|
||||
};
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* semop's sops parameter structure
|
||||
@ -43,15 +97,6 @@ struct sembuf {
|
||||
};
|
||||
#define SEM_UNDO 010000 /* undo changes on process exit */
|
||||
|
||||
/*
|
||||
* semctl's arg parameter structure
|
||||
*/
|
||||
union semun {
|
||||
int val; /* value for SETVAL */
|
||||
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
|
||||
u_short *array; /* array for GETALL & SETALL */
|
||||
};
|
||||
|
||||
/*
|
||||
* commands for semctl
|
||||
*/
|
||||
@ -147,7 +192,7 @@ struct seminfo seminfo;
|
||||
* Structures allocated in machdep.c
|
||||
*/
|
||||
struct semid_ds *sema; /* semaphore id pool */
|
||||
struct sem *sem; /* semaphore pool */
|
||||
struct __sem *sem; /* semaphore pool */
|
||||
struct map *semmap; /* semaphore allocation map */
|
||||
struct sem_undo *semu_list; /* list of active undo structures */
|
||||
int *semu; /* undo structure pool */
|
||||
@ -168,17 +213,27 @@ int *semu; /* undo structure pool */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int semctl __P((int, int, int, union semun));
|
||||
int __semctl __P((int, int, int, union semun *));
|
||||
int semget __P((key_t, int, int));
|
||||
int semop __P((int, struct sembuf *, size_t));
|
||||
#if defined(__LIBC12_SOURCE__)
|
||||
int semctl __P((int, int, int, union __semun));
|
||||
int __semctl __P((int, int, int, union __semun *));
|
||||
int __semctl13 __P((int, int, int, ...));
|
||||
#else
|
||||
int semctl __P((int, int, int, ...)) __RENAME(__semctl13);
|
||||
#endif
|
||||
int semget __P((key_t, int, int));
|
||||
int semop __P((int, struct sembuf *, size_t));
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
int semconfig __P((int));
|
||||
int semconfig __P((int));
|
||||
#endif
|
||||
__END_DECLS
|
||||
#else
|
||||
void seminit __P((void));
|
||||
void semexit __P((struct proc *));
|
||||
void seminit __P((void));
|
||||
void semexit __P((struct proc *));
|
||||
|
||||
int semctl1 __P((struct proc *, int, int, int, void *, register_t *));
|
||||
|
||||
void semid_ds14_to_native __P((struct semid_ds14 *, struct semid_ds *));
|
||||
void native_to_semid_ds14 __P((struct semid_ds *, struct semid_ds14 *));
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* !_SEM_H_ */
|
||||
|
@ -1,4 +1,41 @@
|
||||
/* $NetBSD: shm.h,v 1.22 1998/05/07 16:57:58 kleink Exp $ */
|
||||
/* $NetBSD: shm.h,v 1.23 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Adam Glass
|
||||
@ -46,8 +83,28 @@
|
||||
#define SHM_RND 020000 /* Round attach address to SHMLBA */
|
||||
#define SHMLBA CLBYTES /* Segment low boundry address multiple XXX */
|
||||
|
||||
typedef unsigned int shmatt_t;
|
||||
|
||||
struct shmid_ds {
|
||||
struct ipc_perm shm_perm; /* operation permission structure */
|
||||
size_t shm_segsz; /* size of segment in bytes */
|
||||
pid_t shm_lpid; /* process ID of last shm operation */
|
||||
pid_t shm_cpid; /* process ID of creator */
|
||||
shmatt_t shm_nattch; /* number of current attaches */
|
||||
time_t shm_atime; /* time of last shmat() */
|
||||
time_t shm_dtime; /* time of last shmdt() */
|
||||
time_t shm_ctime; /* time of last change by shmctl() */
|
||||
|
||||
/*
|
||||
* These members are private and used only in the internal
|
||||
* implementation of this interface.
|
||||
*/
|
||||
void *_shm_internal;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct shmid_ds14 {
|
||||
struct ipc_perm14 shm_perm; /* operation permission structure */
|
||||
int shm_segsz; /* size of segment in bytes */
|
||||
pid_t shm_lpid; /* process ID of last shm op */
|
||||
pid_t shm_cpid; /* process ID of creator */
|
||||
@ -58,13 +115,14 @@ struct shmid_ds {
|
||||
void *shm_internal; /* sysv stupidity */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
#if !defined(_XOPEN_SOURCE)
|
||||
/*
|
||||
* Some systems (e.g. HP-UX) take these as the second (cmd) arg to shmctl().
|
||||
* XXX Currently not implemented.
|
||||
*/
|
||||
#define SHM_LOCK 3 /* Lock segment in memory. */
|
||||
#define SHM_UNLOCK 4 /* Unlock a segment locked by SHM_LOCK. */
|
||||
#endif /* _XOPEN_SOURCE */
|
||||
|
||||
/*
|
||||
* System 5 style catch-all structure for shared memory constants that
|
||||
@ -82,19 +140,22 @@ struct shmid_ds *shmsegs;
|
||||
|
||||
struct vmspace;
|
||||
|
||||
void shminit __P((void));
|
||||
void shmfork __P((struct vmspace *, struct vmspace *));
|
||||
void shmexit __P((struct vmspace *));
|
||||
void shminit __P((void));
|
||||
void shmfork __P((struct vmspace *, struct vmspace *));
|
||||
void shmexit __P((struct vmspace *));
|
||||
int shmctl1 __P((struct proc *, int, int, struct shmid_ds *));
|
||||
|
||||
void shmid_ds14_to_native __P((struct shmid_ds14 *, struct shmid_ds *));
|
||||
void native_to_shmid_ds14 __P((struct shmid_ds *, struct shmid_ds14 *));
|
||||
#else /* !_KERNEL */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
void *shmat __P((int, const void *, int));
|
||||
int shmctl __P((int, int, struct shmid_ds *));
|
||||
int shmdt __P((const void *));
|
||||
int shmget __P((key_t, size_t, int));
|
||||
void *shmat __P((int, const void *, int));
|
||||
int shmctl __P((int, int, struct shmid_ds *)) __RENAME(__shmctl13);
|
||||
int shmdt __P((const void *));
|
||||
int shmget __P((key_t, size_t, int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: types.h,v 1.38 1999/08/10 21:09:18 thorpej Exp $ */
|
||||
/* $NetBSD: types.h,v 1.39 1999/08/25 05:05:49 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1991, 1993, 1994
|
||||
@ -86,6 +86,19 @@ typedef int32_t segsz_t; /* segment size */
|
||||
typedef int32_t swblk_t; /* swap offset */
|
||||
typedef u_int32_t uid_t; /* user id */
|
||||
|
||||
#if defined(_KERNEL) || defined(_LIBC)
|
||||
/*
|
||||
* semctl(2)'s argument structure. This is here for the benefit of
|
||||
* <sys/syscallargs.h>. It is not in the user's namespace in SUSv2.
|
||||
* The SUSv2 semctl(2) takes variable arguments.
|
||||
*/
|
||||
union __semun {
|
||||
int val; /* value for SETVAL */
|
||||
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
|
||||
unsigned short *array; /* array for GETALL & SETALL */
|
||||
};
|
||||
#endif /* _KERNEL || __LIBC12_SOURCE__ */
|
||||
|
||||
/*
|
||||
* These belong in unistd.h, but are placed here too to ensure that
|
||||
* long arguments will be promoted to off_t if the program fails to
|
||||
|
Loading…
x
Reference in New Issue
Block a user