Giant Pushdown: sysv shm, sem, and msg calls.
This commit is contained in:
parent
f99a696093
commit
b6a4b4f9ae
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=82607
@ -3,7 +3,7 @@
|
||||
*
|
||||
* DO NOT EDIT-- this file is automatically generated.
|
||||
* $FreeBSD$
|
||||
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.91 2001/05/29 09:22:22 phk Exp
|
||||
* created from FreeBSD: src/sys/kern/syscalls.master,v 1.92 2001/08/30 18:50:56 dillon Exp
|
||||
*/
|
||||
|
||||
#include "opt_compat.h"
|
||||
@ -191,9 +191,9 @@ struct sysent sysent[] = {
|
||||
{ AS(rtprio_args), (sy_call_t *)rtprio }, /* 166 = rtprio */
|
||||
{ 0, (sy_call_t *)nosys }, /* 167 = nosys */
|
||||
{ 0, (sy_call_t *)nosys }, /* 168 = nosys */
|
||||
{ AS(semsys_args), (sy_call_t *)lkmressys }, /* 169 = semsys */
|
||||
{ AS(msgsys_args), (sy_call_t *)lkmressys }, /* 170 = msgsys */
|
||||
{ AS(shmsys_args), (sy_call_t *)lkmressys }, /* 171 = shmsys */
|
||||
{ SYF_MPSAFE | AS(semsys_args), (sy_call_t *)lkmressys }, /* 169 = semsys */
|
||||
{ SYF_MPSAFE | AS(msgsys_args), (sy_call_t *)lkmressys }, /* 170 = msgsys */
|
||||
{ SYF_MPSAFE | AS(shmsys_args), (sy_call_t *)lkmressys }, /* 171 = shmsys */
|
||||
{ 0, (sy_call_t *)nosys }, /* 172 = nosys */
|
||||
{ AS(pread_args), (sy_call_t *)pread }, /* 173 = pread */
|
||||
{ AS(pwrite_args), (sy_call_t *)pwrite }, /* 174 = pwrite */
|
||||
@ -242,18 +242,18 @@ struct sysent sysent[] = {
|
||||
{ 0, (sy_call_t *)lkmnosys }, /* 217 = lkmnosys */
|
||||
{ 0, (sy_call_t *)lkmnosys }, /* 218 = lkmnosys */
|
||||
{ 0, (sy_call_t *)lkmnosys }, /* 219 = lkmnosys */
|
||||
{ AS(__semctl_args), (sy_call_t *)lkmressys }, /* 220 = __semctl */
|
||||
{ AS(semget_args), (sy_call_t *)lkmressys }, /* 221 = semget */
|
||||
{ AS(semop_args), (sy_call_t *)lkmressys }, /* 222 = semop */
|
||||
{ SYF_MPSAFE | AS(__semctl_args), (sy_call_t *)lkmressys }, /* 220 = __semctl */
|
||||
{ SYF_MPSAFE | AS(semget_args), (sy_call_t *)lkmressys }, /* 221 = semget */
|
||||
{ SYF_MPSAFE | AS(semop_args), (sy_call_t *)lkmressys }, /* 222 = semop */
|
||||
{ 0, (sy_call_t *)nosys }, /* 223 = semconfig */
|
||||
{ AS(msgctl_args), (sy_call_t *)lkmressys }, /* 224 = msgctl */
|
||||
{ AS(msgget_args), (sy_call_t *)lkmressys }, /* 225 = msgget */
|
||||
{ AS(msgsnd_args), (sy_call_t *)lkmressys }, /* 226 = msgsnd */
|
||||
{ AS(msgrcv_args), (sy_call_t *)lkmressys }, /* 227 = msgrcv */
|
||||
{ AS(shmat_args), (sy_call_t *)lkmressys }, /* 228 = shmat */
|
||||
{ AS(shmctl_args), (sy_call_t *)lkmressys }, /* 229 = shmctl */
|
||||
{ AS(shmdt_args), (sy_call_t *)lkmressys }, /* 230 = shmdt */
|
||||
{ AS(shmget_args), (sy_call_t *)lkmressys }, /* 231 = shmget */
|
||||
{ SYF_MPSAFE | AS(msgctl_args), (sy_call_t *)lkmressys }, /* 224 = msgctl */
|
||||
{ SYF_MPSAFE | AS(msgget_args), (sy_call_t *)lkmressys }, /* 225 = msgget */
|
||||
{ SYF_MPSAFE | AS(msgsnd_args), (sy_call_t *)lkmressys }, /* 226 = msgsnd */
|
||||
{ SYF_MPSAFE | AS(msgrcv_args), (sy_call_t *)lkmressys }, /* 227 = msgrcv */
|
||||
{ SYF_MPSAFE | AS(shmat_args), (sy_call_t *)lkmressys }, /* 228 = shmat */
|
||||
{ SYF_MPSAFE | AS(shmctl_args), (sy_call_t *)lkmressys }, /* 229 = shmctl */
|
||||
{ SYF_MPSAFE | AS(shmdt_args), (sy_call_t *)lkmressys }, /* 230 = shmdt */
|
||||
{ SYF_MPSAFE | AS(shmget_args), (sy_call_t *)lkmressys }, /* 231 = shmget */
|
||||
{ AS(clock_gettime_args), (sy_call_t *)clock_gettime }, /* 232 = clock_gettime */
|
||||
{ AS(clock_settime_args), (sy_call_t *)clock_settime }, /* 233 = clock_settime */
|
||||
{ AS(clock_getres_args), (sy_call_t *)clock_getres }, /* 234 = clock_getres */
|
||||
|
@ -263,15 +263,15 @@
|
||||
167 UNIMPL NOHIDE nosys
|
||||
168 UNIMPL NOHIDE nosys
|
||||
; 169 is initialized by the SYSVSEM code if present or loaded
|
||||
169 NOSTD BSD { int semsys(int which, int a2, int a3, int a4, \
|
||||
169 MNOSTD BSD { int semsys(int which, int a2, int a3, int a4, \
|
||||
int a5); }
|
||||
; 169 is initialized by the SYSVMSG code if present or loaded
|
||||
; XXX should be { int semsys(int which, ...); }
|
||||
170 NOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \
|
||||
170 MNOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \
|
||||
int a5, int a6); }
|
||||
; 169 is initialized by the SYSVSHM code if present or loaded
|
||||
; XXX should be { int msgsys(int which, ...); }
|
||||
171 NOSTD BSD { int shmsys(int which, int a2, int a3, int a4); }
|
||||
171 MNOSTD BSD { int shmsys(int which, int a2, int a3, int a4); }
|
||||
; XXX should be { int shmsys(int which, ...); }
|
||||
172 UNIMPL NOHIDE nosys
|
||||
173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \
|
||||
@ -345,24 +345,24 @@
|
||||
;
|
||||
; The following were introduced with NetBSD/4.4Lite-2
|
||||
; They are initialized by thier respective modules/sysinits
|
||||
220 NOSTD BSD { int __semctl(int semid, int semnum, int cmd, \
|
||||
220 MNOSTD BSD { int __semctl(int semid, int semnum, int cmd, \
|
||||
union semun *arg); }
|
||||
221 NOSTD BSD { int semget(key_t key, int nsems, int semflg); }
|
||||
222 NOSTD BSD { int semop(int semid, struct sembuf *sops, \
|
||||
221 MNOSTD BSD { int semget(key_t key, int nsems, int semflg); }
|
||||
222 MNOSTD BSD { int semop(int semid, struct sembuf *sops, \
|
||||
u_int nsops); }
|
||||
223 UNIMPL NOHIDE semconfig
|
||||
224 NOSTD BSD { int msgctl(int msqid, int cmd, \
|
||||
224 MNOSTD BSD { int msgctl(int msqid, int cmd, \
|
||||
struct msqid_ds *buf); }
|
||||
225 NOSTD BSD { int msgget(key_t key, int msgflg); }
|
||||
226 NOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
||||
225 MNOSTD BSD { int msgget(key_t key, int msgflg); }
|
||||
226 MNOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \
|
||||
int msgflg); }
|
||||
227 NOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
||||
227 MNOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \
|
||||
long msgtyp, int msgflg); }
|
||||
228 NOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); }
|
||||
229 NOSTD BSD { int shmctl(int shmid, int cmd, \
|
||||
228 MNOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); }
|
||||
229 MNOSTD BSD { int shmctl(int shmid, int cmd, \
|
||||
struct shmid_ds *buf); }
|
||||
230 NOSTD BSD { int shmdt(void *shmaddr); }
|
||||
231 NOSTD BSD { int shmget(key_t key, int size, int shmflg); }
|
||||
230 MNOSTD BSD { int shmdt(void *shmaddr); }
|
||||
231 MNOSTD BSD { int shmget(key_t key, int size, int shmflg); }
|
||||
;
|
||||
232 STD POSIX { int clock_gettime(clockid_t clock_id, \
|
||||
struct timespec *tp); }
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysent.h>
|
||||
@ -263,6 +265,8 @@ MODULE_VERSION(sysvmsg, 1);
|
||||
|
||||
/*
|
||||
* Entry point for all MSG calls
|
||||
*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
msgsys(p, uap)
|
||||
@ -277,13 +281,22 @@ msgsys(p, uap)
|
||||
int a6;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
|
||||
return (EINVAL);
|
||||
return ((*msgcalls[uap->which])(p, &uap->a2));
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
error = (*msgcalls[uap->which])(p, &uap->a2);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -318,6 +331,9 @@ struct msgctl_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
msgctl(p, uap)
|
||||
struct proc *p;
|
||||
@ -326,16 +342,19 @@ msgctl(p, uap)
|
||||
int msqid = uap->msqid;
|
||||
int cmd = uap->cmd;
|
||||
struct msqid_ds *user_msqptr = uap->buf;
|
||||
int rval, eval;
|
||||
int rval, error;
|
||||
struct msqid_ds msqbuf;
|
||||
register struct msqid_ds *msqptr;
|
||||
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
|
||||
#endif
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqid = IPCID_TO_IX(msqid);
|
||||
|
||||
@ -344,7 +363,8 @@ msgctl(p, uap)
|
||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
@ -353,16 +373,18 @@ msgctl(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("no such msqid\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("wrong sequence number\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
eval = 0;
|
||||
error = 0;
|
||||
rval = 0;
|
||||
|
||||
switch (cmd) {
|
||||
@ -370,8 +392,8 @@ msgctl(p, uap)
|
||||
case IPC_RMID:
|
||||
{
|
||||
struct msg *msghdr;
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||
goto done2;
|
||||
/* Free the message headers */
|
||||
msghdr = msqptr->msg_first;
|
||||
while (msghdr != NULL) {
|
||||
@ -398,14 +420,14 @@ msgctl(p, uap)
|
||||
break;
|
||||
|
||||
case IPC_SET:
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||
return(eval);
|
||||
if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_M)))
|
||||
goto done2;
|
||||
if ((error = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
|
||||
goto done2;
|
||||
if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
|
||||
eval = suser(p);
|
||||
if (eval)
|
||||
return(eval);
|
||||
error = suser(p);
|
||||
if (error)
|
||||
goto done2;
|
||||
}
|
||||
if (msqbuf.msg_qbytes > msginfo.msgmnb) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
@ -418,7 +440,8 @@ msgctl(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("can't reduce msg_qbytes to 0\n");
|
||||
#endif
|
||||
return(EINVAL); /* non-standard errno! */
|
||||
error = EINVAL; /* non-standard errno! */
|
||||
goto done2;
|
||||
}
|
||||
msqptr->msg_perm.uid = msqbuf.msg_perm.uid; /* change the owner */
|
||||
msqptr->msg_perm.gid = msqbuf.msg_perm.gid; /* change the owner */
|
||||
@ -429,13 +452,13 @@ msgctl(p, uap)
|
||||
break;
|
||||
|
||||
case IPC_STAT:
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("requester doesn't have read access\n");
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
eval = copyout((caddr_t)msqptr, user_msqptr,
|
||||
error = copyout((caddr_t)msqptr, user_msqptr,
|
||||
sizeof(struct msqid_ds));
|
||||
break;
|
||||
|
||||
@ -443,12 +466,15 @@ msgctl(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("invalid command %d\n", cmd);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (eval == 0)
|
||||
if (error == 0)
|
||||
p->p_retval[0] = rval;
|
||||
return(eval);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -458,12 +484,15 @@ struct msgget_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
msgget(p, uap)
|
||||
struct proc *p;
|
||||
register struct msgget_args *uap;
|
||||
{
|
||||
int msqid, eval;
|
||||
int msqid, error = 0;
|
||||
int key = uap->key;
|
||||
int msgflg = uap->msgflg;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
@ -473,8 +502,12 @@ msgget(p, uap)
|
||||
printf("msgget(0x%x, 0%o)\n", key, msgflg);
|
||||
#endif
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (key != IPC_PRIVATE) {
|
||||
for (msqid = 0; msqid < msginfo.msgmni; msqid++) {
|
||||
@ -491,14 +524,15 @@ msgget(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("not exclusive\n");
|
||||
#endif
|
||||
return(EEXIST);
|
||||
error = EEXIST;
|
||||
goto done2;
|
||||
}
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, msgflg & 0700 ))) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("requester doesn't have 0%o access\n",
|
||||
msgflg & 0700);
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
@ -524,7 +558,8 @@ msgget(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("no more msqid_ds's available\n");
|
||||
#endif
|
||||
return(ENOSPC);
|
||||
error = ENOSPC;
|
||||
goto done2;
|
||||
}
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msqid %d is available\n", msqid);
|
||||
@ -551,13 +586,16 @@ msgget(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("didn't find it and wasn't asked to create it\n");
|
||||
#endif
|
||||
return(ENOENT);
|
||||
error = ENOENT;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
found:
|
||||
/* Construct the unique msqid */
|
||||
p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm);
|
||||
return(0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -569,6 +607,9 @@ struct msgsnd_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
msgsnd(p, uap)
|
||||
struct proc *p;
|
||||
@ -578,7 +619,7 @@ msgsnd(p, uap)
|
||||
void *user_msgp = uap->msgp;
|
||||
size_t msgsz = uap->msgsz;
|
||||
int msgflg = uap->msgflg;
|
||||
int segs_needed, eval;
|
||||
int segs_needed, error = 0;
|
||||
register struct msqid_ds *msqptr;
|
||||
register struct msg *msghdr;
|
||||
short next;
|
||||
@ -587,9 +628,12 @@ msgsnd(p, uap)
|
||||
printf("call to msgsnd(%d, 0x%x, %d, %d)\n", msqid, user_msgp, msgsz,
|
||||
msgflg);
|
||||
#endif
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqid = IPCID_TO_IX(msqid);
|
||||
|
||||
@ -598,7 +642,8 @@ msgsnd(p, uap)
|
||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
@ -606,20 +651,22 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("no such message queue id\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("wrong sequence number\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_W))) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("requester doesn't have write access\n");
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
|
||||
@ -639,7 +686,8 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msgsz > msqptr->msg_qbytes\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (msqptr->msg_perm.mode & MSG_LOCKED) {
|
||||
@ -674,7 +722,8 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("need more resources but caller doesn't want to wait\n");
|
||||
#endif
|
||||
return(EAGAIN);
|
||||
error = EAGAIN;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if ((msqptr->msg_perm.mode & MSG_LOCKED) != 0) {
|
||||
@ -694,18 +743,19 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("goodnight\n");
|
||||
#endif
|
||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
|
||||
error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH,
|
||||
"msgwait", 0);
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("good morning, eval=%d\n", eval);
|
||||
printf("good morning, error=%d\n", error);
|
||||
#endif
|
||||
if (we_own_it)
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
if (eval != 0) {
|
||||
if (error != 0) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msgsnd: interrupted system call\n");
|
||||
#endif
|
||||
return(EINTR);
|
||||
error = EINTR;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -716,7 +766,8 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msqid deleted\n");
|
||||
#endif
|
||||
return(EIDRM);
|
||||
error = EIDRM;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -787,15 +838,15 @@ msgsnd(p, uap)
|
||||
* 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) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("error %d copying the message type\n", eval);
|
||||
printf("error %d copying the message type\n", error);
|
||||
#endif
|
||||
msg_freehdr(msghdr);
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
||||
|
||||
@ -810,7 +861,8 @@ msgsnd(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("mtype (%d) < 1\n", msghdr->msg_type);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -828,15 +880,15 @@ msgsnd(p, uap)
|
||||
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) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("error %d copying in message segment\n", eval);
|
||||
printf("error %d copying in message segment\n", error);
|
||||
#endif
|
||||
msg_freehdr(msghdr);
|
||||
msqptr->msg_perm.mode &= ~MSG_LOCKED;
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
msgsz -= tlen;
|
||||
user_msgp = (char *)user_msgp + tlen;
|
||||
@ -858,7 +910,8 @@ msgsnd(p, uap)
|
||||
if (msqptr->msg_qbytes == 0) {
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(EIDRM);
|
||||
error = EIDRM;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -881,7 +934,9 @@ msgsnd(p, uap)
|
||||
|
||||
wakeup((caddr_t)msqptr);
|
||||
p->p_retval[0] = 0;
|
||||
return(0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -894,6 +949,9 @@ struct msgrcv_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
msgrcv(p, uap)
|
||||
struct proc *p;
|
||||
@ -907,7 +965,7 @@ msgrcv(p, uap)
|
||||
size_t len;
|
||||
register struct msqid_ds *msqptr;
|
||||
register struct msg *msghdr;
|
||||
int eval;
|
||||
int error = 0;
|
||||
short next;
|
||||
|
||||
#ifdef MSG_DEBUG_OK
|
||||
@ -915,8 +973,12 @@ msgrcv(p, uap)
|
||||
msgsz, msgtyp, msgflg);
|
||||
#endif
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqid = IPCID_TO_IX(msqid);
|
||||
|
||||
@ -925,7 +987,8 @@ msgrcv(p, uap)
|
||||
printf("msqid (%d) out of range (0<=msqid<%d)\n", msqid,
|
||||
msginfo.msgmni);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msqptr = &msqids[msqid];
|
||||
@ -933,20 +996,22 @@ msgrcv(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("no such message queue id\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (msqptr->msg_perm.seq != IPCID_TO_SEQ(uap->msqid)) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("wrong sequence number\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if ((eval = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||
if ((error = ipcperm(p, &msqptr->msg_perm, IPC_R))) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("requester doesn't have read access\n");
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
msghdr = NULL;
|
||||
@ -960,7 +1025,8 @@ msgrcv(p, uap)
|
||||
printf("first message on the queue is too big (want %d, got %d)\n",
|
||||
msgsz, msghdr->msg_ts);
|
||||
#endif
|
||||
return(E2BIG);
|
||||
error = E2BIG;
|
||||
goto done2;
|
||||
}
|
||||
if (msqptr->msg_first == msqptr->msg_last) {
|
||||
msqptr->msg_first = NULL;
|
||||
@ -999,7 +1065,8 @@ msgrcv(p, uap)
|
||||
printf("requested message on the queue is too big (want %d, got %d)\n",
|
||||
msgsz, msghdr->msg_ts);
|
||||
#endif
|
||||
return(E2BIG);
|
||||
error = E2BIG;
|
||||
goto done2;
|
||||
}
|
||||
*prev = msghdr->msg_next;
|
||||
if (msghdr == msqptr->msg_last) {
|
||||
@ -1045,7 +1112,8 @@ msgrcv(p, uap)
|
||||
msgtyp);
|
||||
#endif
|
||||
/* The SVID says to return ENOMSG. */
|
||||
return(ENOMSG);
|
||||
error = ENOMSG;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1055,17 +1123,18 @@ msgrcv(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msgrcv: goodnight\n");
|
||||
#endif
|
||||
eval = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
||||
error = tsleep((caddr_t)msqptr, (PZERO - 4) | PCATCH, "msgwait",
|
||||
0);
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msgrcv: good morning (eval=%d)\n", eval);
|
||||
printf("msgrcv: good morning (error=%d)\n", error);
|
||||
#endif
|
||||
|
||||
if (eval != 0) {
|
||||
if (error != 0) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msgsnd: interrupted system call\n");
|
||||
#endif
|
||||
return(EINTR);
|
||||
error = EINTR;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1077,7 +1146,8 @@ msgrcv(p, uap)
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("msqid deleted\n");
|
||||
#endif
|
||||
return(EIDRM);
|
||||
error = EIDRM;
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,15 +1179,15 @@ msgrcv(p, uap)
|
||||
* Return the type to the user.
|
||||
*/
|
||||
|
||||
eval = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
|
||||
error = copyout((caddr_t)&(msghdr->msg_type), user_msgp,
|
||||
sizeof(msghdr->msg_type));
|
||||
if (eval != 0) {
|
||||
if (error != 0) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("error (%d) copying out message type\n", eval);
|
||||
printf("error (%d) copying out message type\n", error);
|
||||
#endif
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
user_msgp = (char *)user_msgp + sizeof(msghdr->msg_type);
|
||||
|
||||
@ -1137,16 +1207,16 @@ msgrcv(p, uap)
|
||||
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((caddr_t)&msgpool[next * msginfo.msgssz],
|
||||
user_msgp, tlen);
|
||||
if (eval != 0) {
|
||||
if (error != 0) {
|
||||
#ifdef MSG_DEBUG_OK
|
||||
printf("error (%d) copying out message segment\n",
|
||||
eval);
|
||||
error);
|
||||
#endif
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
user_msgp = (char *)user_msgp + tlen;
|
||||
next = msgmaps[next].next;
|
||||
@ -1159,7 +1229,9 @@ msgrcv(p, uap)
|
||||
msg_freehdr(msghdr);
|
||||
wakeup((caddr_t)msqptr);
|
||||
p->p_retval[0] = msgsz;
|
||||
return(0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysent.h>
|
||||
@ -244,6 +246,8 @@ MODULE_VERSION(sysvsem, 1);
|
||||
|
||||
/*
|
||||
* Entry point for all SEM calls
|
||||
*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
semsys(p, uap)
|
||||
@ -257,13 +261,23 @@ semsys(p, uap)
|
||||
int a5;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
|
||||
return (EINVAL);
|
||||
return ((*semcalls[uap->which])(p, &uap->a2));
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0])) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
error = (*semcalls[uap->which])(p, &uap->a2);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -448,6 +462,9 @@ struct __semctl_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
__semctl(p, uap)
|
||||
struct proc *p;
|
||||
@ -459,33 +476,40 @@ __semctl(p, uap)
|
||||
union semun *arg = uap->arg;
|
||||
union semun real_arg;
|
||||
struct ucred *cred = p->p_ucred;
|
||||
int i, rval, eval;
|
||||
int i, rval, error;
|
||||
struct semid_ds sbuf;
|
||||
register struct semid_ds *semaptr;
|
||||
|
||||
#ifdef SEM_DEBUG
|
||||
printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
|
||||
#endif
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
semid = IPCID_TO_IX(semid);
|
||||
if (semid < 0 || semid >= seminfo.semmsl)
|
||||
return(EINVAL);
|
||||
if (semid < 0 || semid >= seminfo.semmsl) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
semaptr = &sema[semid];
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
||||
return(EINVAL);
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
eval = 0;
|
||||
error = 0;
|
||||
rval = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case IPC_RMID:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
||||
goto done2;
|
||||
semaptr->sem_perm.cuid = cred->cr_uid;
|
||||
semaptr->sem_perm.uid = cred->cr_uid;
|
||||
semtot -= semaptr->sem_nsems;
|
||||
@ -502,13 +526,14 @@ __semctl(p, uap)
|
||||
break;
|
||||
|
||||
case IPC_SET:
|
||||
if ((eval = ipcperm(p, &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);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_M)))
|
||||
goto done2;
|
||||
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
goto done2;
|
||||
if ((error = copyin(real_arg.buf, (caddr_t)&sbuf,
|
||||
sizeof(sbuf))) != 0) {
|
||||
goto done2;
|
||||
}
|
||||
semaptr->sem_perm.uid = sbuf.sem_perm.uid;
|
||||
semaptr->sem_perm.gid = sbuf.sem_perm.gid;
|
||||
semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) |
|
||||
@ -517,81 +542,91 @@ __semctl(p, uap)
|
||||
break;
|
||||
|
||||
case IPC_STAT:
|
||||
if ((eval = ipcperm(p, &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(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
goto done2;
|
||||
error = copyout((caddr_t)semaptr, real_arg.buf,
|
||||
sizeof(struct semid_ds));
|
||||
break;
|
||||
|
||||
case GETNCNT:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
rval = semaptr->sem_base[semnum].semncnt;
|
||||
break;
|
||||
|
||||
case GETPID:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
rval = semaptr->sem_base[semnum].sempid;
|
||||
break;
|
||||
|
||||
case GETVAL:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
rval = semaptr->sem_base[semnum].semval;
|
||||
break;
|
||||
|
||||
case GETALL:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
goto done2;
|
||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||
eval = copyout((caddr_t)&semaptr->sem_base[i].semval,
|
||||
error = copyout((caddr_t)&semaptr->sem_base[i].semval,
|
||||
&real_arg.array[i], sizeof(real_arg.array[0]));
|
||||
if (eval != 0)
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case GETZCNT:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
return(eval);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_R)))
|
||||
goto done2;
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
rval = semaptr->sem_base[semnum].semzcnt;
|
||||
break;
|
||||
|
||||
case SETVAL:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||
return(eval);
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems)
|
||||
return(EINVAL);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||
goto done2;
|
||||
if (semnum < 0 || semnum >= semaptr->sem_nsems) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
goto done2;
|
||||
semaptr->sem_base[semnum].semval = real_arg.val;
|
||||
semundo_clear(semid, semnum);
|
||||
wakeup((caddr_t)semaptr);
|
||||
break;
|
||||
|
||||
case SETALL:
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||
return(eval);
|
||||
if ((eval = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W)))
|
||||
goto done2;
|
||||
if ((error = copyin(arg, &real_arg, sizeof(real_arg))) != 0)
|
||||
goto done2;
|
||||
for (i = 0; i < semaptr->sem_nsems; i++) {
|
||||
eval = copyin(&real_arg.array[i],
|
||||
error = copyin(&real_arg.array[i],
|
||||
(caddr_t)&semaptr->sem_base[i].semval,
|
||||
sizeof(real_arg.array[0]));
|
||||
if (eval != 0)
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
semundo_clear(semid, -1);
|
||||
@ -599,12 +634,15 @@ __semctl(p, uap)
|
||||
break;
|
||||
|
||||
default:
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (eval == 0)
|
||||
if (error == 0)
|
||||
p->p_retval[0] = rval;
|
||||
return(eval);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -615,12 +653,15 @@ struct semget_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
semget(p, uap)
|
||||
struct proc *p;
|
||||
register struct semget_args *uap;
|
||||
{
|
||||
int semid, eval;
|
||||
int semid, error = 0;
|
||||
int key = uap->key;
|
||||
int nsems = uap->nsems;
|
||||
int semflg = uap->semflg;
|
||||
@ -629,9 +670,12 @@ semget(p, uap)
|
||||
#ifdef SEM_DEBUG
|
||||
printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
|
||||
#endif
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (key != IPC_PRIVATE) {
|
||||
for (semid = 0; semid < seminfo.semmni; semid++) {
|
||||
@ -643,20 +687,23 @@ semget(p, uap)
|
||||
#ifdef SEM_DEBUG
|
||||
printf("found public key\n");
|
||||
#endif
|
||||
if ((eval = ipcperm(p, &sema[semid].sem_perm,
|
||||
semflg & 0700)))
|
||||
return(eval);
|
||||
if ((error = ipcperm(p, &sema[semid].sem_perm,
|
||||
semflg & 0700))) {
|
||||
goto done2;
|
||||
}
|
||||
if (nsems > 0 && sema[semid].sem_nsems < nsems) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("too small\n");
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if ((semflg & IPC_CREAT) && (semflg & IPC_EXCL)) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("not exclusive\n");
|
||||
#endif
|
||||
return(EEXIST);
|
||||
error = EEXIST;
|
||||
goto done2;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
@ -671,14 +718,16 @@ semget(p, uap)
|
||||
printf("nsems out of range (0<%d<=%d)\n", nsems,
|
||||
seminfo.semmsl);
|
||||
#endif
|
||||
return(EINVAL);
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (nsems > seminfo.semmns - semtot) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("not enough semaphores left (need %d, got %d)\n",
|
||||
nsems, seminfo.semmns - semtot);
|
||||
#endif
|
||||
return(ENOSPC);
|
||||
error = ENOSPC;
|
||||
goto done2;
|
||||
}
|
||||
for (semid = 0; semid < seminfo.semmni; semid++) {
|
||||
if ((sema[semid].sem_perm.mode & SEM_ALLOC) == 0)
|
||||
@ -688,7 +737,8 @@ semget(p, uap)
|
||||
#ifdef SEM_DEBUG
|
||||
printf("no more semid_ds's available\n");
|
||||
#endif
|
||||
return(ENOSPC);
|
||||
error = ENOSPC;
|
||||
goto done2;
|
||||
}
|
||||
#ifdef SEM_DEBUG
|
||||
printf("semid %d is available\n", semid);
|
||||
@ -716,12 +766,15 @@ semget(p, uap)
|
||||
#ifdef SEM_DEBUG
|
||||
printf("didn't find it and wasn't asked to create it\n");
|
||||
#endif
|
||||
return(ENOENT);
|
||||
error = ENOENT;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
found:
|
||||
p->p_retval[0] = IXSEQ_TO_IPCID(semid, sema[semid].sem_perm);
|
||||
return(0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -732,6 +785,9 @@ struct semop_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
semop(p, uap)
|
||||
struct proc *p;
|
||||
@ -744,47 +800,58 @@ semop(p, uap)
|
||||
register struct sembuf *sopptr;
|
||||
register struct sem *semptr;
|
||||
struct sem_undo *suptr = NULL;
|
||||
int i, j, eval;
|
||||
int i, j, error = 0;
|
||||
int do_wakeup, do_undos;
|
||||
|
||||
#ifdef SEM_DEBUG
|
||||
printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops);
|
||||
#endif
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
semid = IPCID_TO_IX(semid); /* Convert back to zero origin */
|
||||
|
||||
if (semid < 0 || semid >= seminfo.semmsl)
|
||||
return(EINVAL);
|
||||
if (semid < 0 || semid >= seminfo.semmsl) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
semaptr = &sema[semid];
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
|
||||
return(EINVAL);
|
||||
if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
||||
return(EINVAL);
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
if (semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if ((eval = ipcperm(p, &semaptr->sem_perm, IPC_W))) {
|
||||
if ((error = ipcperm(p, &semaptr->sem_perm, IPC_W))) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("eval = %d from ipaccess\n", eval);
|
||||
printf("error = %d from ipaccess\n", error);
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (nsops > MAX_SOPS) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops);
|
||||
#endif
|
||||
return(E2BIG);
|
||||
error = E2BIG;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if ((eval = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) {
|
||||
if ((error = copyin(uap->sops, &sops, nsops * sizeof(sops[0]))) != 0) {
|
||||
#ifdef SEM_DEBUG
|
||||
printf("eval = %d from copyin(%08x, %08x, %d)\n", eval,
|
||||
printf("error = %d from copyin(%08x, %08x, %d)\n", error,
|
||||
uap->sops, &sops, nsops * sizeof(sops[0]));
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -804,8 +871,10 @@ semop(p, uap)
|
||||
for (i = 0; i < nsops; i++) {
|
||||
sopptr = &sops[i];
|
||||
|
||||
if (sopptr->sem_num >= semaptr->sem_nsems)
|
||||
return(EFBIG);
|
||||
if (sopptr->sem_num >= semaptr->sem_nsems) {
|
||||
error = EFBIG;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
semptr = &semaptr->sem_base[sopptr->sem_num];
|
||||
|
||||
@ -866,8 +935,10 @@ semop(p, uap)
|
||||
* If the request that we couldn't satisfy has the
|
||||
* NOWAIT flag set then return with EAGAIN.
|
||||
*/
|
||||
if (sopptr->sem_flg & IPC_NOWAIT)
|
||||
return(EAGAIN);
|
||||
if (sopptr->sem_flg & IPC_NOWAIT) {
|
||||
error = EAGAIN;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (sopptr->sem_op == 0)
|
||||
semptr->semzcnt++;
|
||||
@ -877,16 +948,18 @@ semop(p, uap)
|
||||
#ifdef SEM_DEBUG
|
||||
printf("semop: good night!\n");
|
||||
#endif
|
||||
eval = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH,
|
||||
error = tsleep((caddr_t)semaptr, (PZERO - 4) | PCATCH,
|
||||
"semwait", 0);
|
||||
#ifdef SEM_DEBUG
|
||||
printf("semop: good morning (eval=%d)!\n", eval);
|
||||
printf("semop: good morning (error=%d)!\n", error);
|
||||
#endif
|
||||
|
||||
suptr = NULL; /* sem_undo may have been reallocated */
|
||||
|
||||
if (eval != 0)
|
||||
return(EINTR);
|
||||
if (error != 0) {
|
||||
error = EINTR;
|
||||
goto done2;
|
||||
}
|
||||
#ifdef SEM_DEBUG
|
||||
printf("semop: good morning!\n");
|
||||
#endif
|
||||
@ -895,8 +968,10 @@ semop(p, uap)
|
||||
* Make sure that the semaphore still exists
|
||||
*/
|
||||
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0 ||
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid))
|
||||
return(EIDRM);
|
||||
semaptr->sem_perm.seq != IPCID_TO_SEQ(uap->semid)) {
|
||||
error = EIDRM;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
* The semaphore is still alive. Readjust the count of
|
||||
@ -925,9 +1000,9 @@ semop(p, uap)
|
||||
adjval = sops[i].sem_op;
|
||||
if (adjval == 0)
|
||||
continue;
|
||||
eval = semundo_adjust(p, &suptr, semid,
|
||||
error = semundo_adjust(p, &suptr, semid,
|
||||
sops[i].sem_num, -adjval);
|
||||
if (eval == 0)
|
||||
if (error == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -955,9 +1030,9 @@ semop(p, uap)
|
||||
sops[j].sem_op;
|
||||
|
||||
#ifdef SEM_DEBUG
|
||||
printf("eval = %d from semundo_adjust\n", eval);
|
||||
printf("error = %d from semundo_adjust\n", error);
|
||||
#endif
|
||||
return(eval);
|
||||
goto done2;
|
||||
} /* loop through the sops */
|
||||
} /* if (do_undos) */
|
||||
|
||||
@ -982,7 +1057,9 @@ semop(p, uap)
|
||||
printf("semop: done\n");
|
||||
#endif
|
||||
p->p_retval[0] = 0;
|
||||
return(0);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -233,6 +233,9 @@ struct shmdt_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
shmdt(p, uap)
|
||||
struct proc *p;
|
||||
@ -240,22 +243,34 @@ shmdt(p, uap)
|
||||
{
|
||||
struct shmmap_state *shmmap_s;
|
||||
int i;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
||||
if (shmmap_s == NULL)
|
||||
return EINVAL;
|
||||
for (i = 0; i < shminfo.shmseg; i++, shmmap_s++)
|
||||
if (shmmap_s == NULL) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
for (i = 0; i < shminfo.shmseg; i++, shmmap_s++) {
|
||||
if (shmmap_s->shmid != -1 &&
|
||||
shmmap_s->va == (vm_offset_t)uap->shmaddr)
|
||||
shmmap_s->va == (vm_offset_t)uap->shmaddr) {
|
||||
break;
|
||||
if (i == shminfo.shmseg)
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
if (i == shminfo.shmseg) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
error = shm_delete_mapping(p, shmmap_s);
|
||||
return error;
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -266,12 +281,15 @@ struct shmat_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
shmat(p, uap)
|
||||
struct proc *p;
|
||||
struct shmat_args *uap;
|
||||
{
|
||||
int error, i, flags;
|
||||
int i, flags;
|
||||
struct shmid_ds *shmseg;
|
||||
struct shmmap_state *shmmap_s = NULL;
|
||||
struct shm_handle *shm_handle;
|
||||
@ -279,11 +297,14 @@ shmat(p, uap)
|
||||
vm_prot_t prot;
|
||||
vm_size_t size;
|
||||
int rv;
|
||||
int error = 0;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
|
||||
if (shmmap_s == NULL) {
|
||||
@ -294,19 +315,23 @@ shmat(p, uap)
|
||||
p->p_vmspace->vm_shm = (caddr_t)shmmap_s;
|
||||
}
|
||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||
if (shmseg == NULL)
|
||||
return EINVAL;
|
||||
if (shmseg == NULL) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
error = ipcperm(p, &shmseg->shm_perm,
|
||||
(uap->shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W);
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
for (i = 0; i < shminfo.shmseg; i++) {
|
||||
if (shmmap_s->shmid == -1)
|
||||
break;
|
||||
shmmap_s++;
|
||||
}
|
||||
if (i >= shminfo.shmseg)
|
||||
return EMFILE;
|
||||
if (i >= shminfo.shmseg) {
|
||||
error = EMFILE;
|
||||
goto done2;
|
||||
}
|
||||
size = round_page(shmseg->shm_segsz);
|
||||
#ifdef VM_PROT_READ_IS_EXEC
|
||||
prot = VM_PROT_READ | VM_PROT_EXECUTE;
|
||||
@ -318,12 +343,14 @@ shmat(p, uap)
|
||||
flags = MAP_ANON | MAP_SHARED;
|
||||
if (uap->shmaddr) {
|
||||
flags |= MAP_FIXED;
|
||||
if (uap->shmflg & SHM_RND)
|
||||
if (uap->shmflg & SHM_RND) {
|
||||
attach_va = (vm_offset_t)uap->shmaddr & ~(SHMLBA-1);
|
||||
else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0)
|
||||
} else if (((vm_offset_t)uap->shmaddr & (SHMLBA-1)) == 0) {
|
||||
attach_va = (vm_offset_t)uap->shmaddr;
|
||||
else
|
||||
return EINVAL;
|
||||
} else {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is just a hint to vm_map_find() about where to
|
||||
@ -338,7 +365,8 @@ shmat(p, uap)
|
||||
rv = vm_map_find(&p->p_vmspace->vm_map, shm_handle->shm_object,
|
||||
0, &attach_va, size, (flags & MAP_FIXED)?0:1, prot, prot, 0);
|
||||
if (rv != KERN_SUCCESS) {
|
||||
return ENOMEM;
|
||||
error = ENOMEM;
|
||||
goto done2;
|
||||
}
|
||||
vm_map_inherit(&p->p_vmspace->vm_map,
|
||||
attach_va, attach_va + size, VM_INHERIT_SHARE);
|
||||
@ -349,7 +377,9 @@ shmat(p, uap)
|
||||
shmseg->shm_atime = time_second;
|
||||
shmseg->shm_nattch++;
|
||||
p->p_retval[0] = attach_va;
|
||||
return 0;
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct oshmid_ds {
|
||||
@ -370,27 +400,36 @@ struct oshmctl_args {
|
||||
struct oshmid_ds *ubuf;
|
||||
};
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
static int
|
||||
oshmctl(p, uap)
|
||||
struct proc *p;
|
||||
struct oshmctl_args *uap;
|
||||
{
|
||||
#ifdef COMPAT_43
|
||||
int error;
|
||||
int error = 0;
|
||||
struct shmid_ds *shmseg;
|
||||
struct oshmid_ds outbuf;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||
if (shmseg == NULL)
|
||||
return EINVAL;
|
||||
if (shmseg == NULL) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
switch (uap->cmd) {
|
||||
case IPC_STAT:
|
||||
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
outbuf.shm_perm = shmseg->shm_perm;
|
||||
outbuf.shm_segsz = shmseg->shm_segsz;
|
||||
outbuf.shm_cpid = shmseg->shm_cpid;
|
||||
@ -402,13 +441,16 @@ oshmctl(p, uap)
|
||||
outbuf.shm_handle = shmseg->shm_internal;
|
||||
error = copyout((caddr_t)&outbuf, uap->ubuf, sizeof(outbuf));
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
break;
|
||||
default:
|
||||
/* XXX casting to (sy_call_t *) is bogus, as usual. */
|
||||
return ((sy_call_t *)shmctl)(p, uap);
|
||||
error = ((sy_call_t *)shmctl)(p, uap);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
#else
|
||||
return EINVAL;
|
||||
#endif
|
||||
@ -422,39 +464,46 @@ struct shmctl_args {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
shmctl(p, uap)
|
||||
struct proc *p;
|
||||
struct shmctl_args *uap;
|
||||
{
|
||||
int error;
|
||||
int error = 0;
|
||||
struct shmid_ds inbuf;
|
||||
struct shmid_ds *shmseg;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||
if (shmseg == NULL)
|
||||
return EINVAL;
|
||||
if (shmseg == NULL) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
switch (uap->cmd) {
|
||||
case IPC_STAT:
|
||||
error = ipcperm(p, &shmseg->shm_perm, IPC_R);
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf));
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
break;
|
||||
case IPC_SET:
|
||||
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
error = copyin(uap->buf, (caddr_t)&inbuf, sizeof(inbuf));
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
shmseg->shm_perm.uid = inbuf.shm_perm.uid;
|
||||
shmseg->shm_perm.gid = inbuf.shm_perm.gid;
|
||||
shmseg->shm_perm.mode =
|
||||
@ -465,7 +514,7 @@ shmctl(p, uap)
|
||||
case IPC_RMID:
|
||||
error = ipcperm(p, &shmseg->shm_perm, IPC_M);
|
||||
if (error)
|
||||
return error;
|
||||
goto done2;
|
||||
shmseg->shm_perm.key = IPC_PRIVATE;
|
||||
shmseg->shm_perm.mode |= SHMSEG_REMOVED;
|
||||
if (shmseg->shm_nattch <= 0) {
|
||||
@ -478,9 +527,12 @@ shmctl(p, uap)
|
||||
case SHM_UNLOCK:
|
||||
#endif
|
||||
default:
|
||||
return EINVAL;
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -607,15 +659,23 @@ shmget_allocate_segment(p, uap, mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
shmget(p, uap)
|
||||
struct proc *p;
|
||||
struct shmget_args *uap;
|
||||
{
|
||||
int segnum, mode, error;
|
||||
int segnum, mode;
|
||||
int error;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
mode = uap->shmflg & ACCESSPERMS;
|
||||
if (uap->key != IPC_PRIVATE) {
|
||||
@ -625,14 +685,22 @@ shmget(p, uap)
|
||||
error = shmget_existing(p, uap, mode, segnum);
|
||||
if (error == EAGAIN)
|
||||
goto again;
|
||||
return error;
|
||||
goto done2;
|
||||
}
|
||||
if ((uap->shmflg & IPC_CREAT) == 0) {
|
||||
error = ENOENT;
|
||||
goto done2;
|
||||
}
|
||||
if ((uap->shmflg & IPC_CREAT) == 0)
|
||||
return ENOENT;
|
||||
}
|
||||
return shmget_allocate_segment(p, uap, mode);
|
||||
error = shmget_allocate_segment(p, uap, mode);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* MPSAFE
|
||||
*/
|
||||
int
|
||||
shmsys(p, uap)
|
||||
struct proc *p;
|
||||
@ -644,13 +712,23 @@ shmsys(p, uap)
|
||||
int a4;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred))
|
||||
return (ENOSYS);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
|
||||
return EINVAL;
|
||||
return ((*shmcalls[uap->which])(p, &uap->a2));
|
||||
if (!jail_sysvipc_allowed && jailed(p->p_ucred)) {
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0])) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
error = (*shmcalls[uap->which])(p, &uap->a2);
|
||||
done2:
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user