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:
thorpej 1999-08-25 05:05:48 +00:00
parent 0174ee34d0
commit dc8ecaa15b
10 changed files with 804 additions and 423 deletions

@ -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

@ -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