--- xnu-517.3.7/bsd/kern/sysv_ipc.c Fri Dec 19 17:36:53 2003 +++ xnu-517.3.7.patched/bsd/kern/sysv_ipc.c Wed Feb 18 13:54:08 2004 @@ -93,70 +93,3 @@ return (0); return ((mode & perm->mode) == mode ? 0 : EACCES); } - - - -/* - * SYSVMSG stubs - */ - -int -msgsys(p, uap) - struct proc *p; - /* XXX actually varargs. */ -#if 0 - struct msgsys_args *uap; -#else - void *uap; -#endif -{ - return(EOPNOTSUPP); -}; - -int -msgctl(p, uap) - struct proc *p; -#if 0 - register struct msgctl_args *uap; -#else - void *uap; -#endif -{ - return(EOPNOTSUPP); -}; - -int -msgget(p, uap) - struct proc *p; -#if 0 - register struct msgget_args *uap; -#else - void *uap; -#endif -{ - return(EOPNOTSUPP); -}; - -int -msgsnd(p, uap) - struct proc *p; -#if 0 - register struct msgsnd_args *uap; -#else - void *uap; -#endif -{ - return(EOPNOTSUPP); -}; - -int -msgrcv(p, uap) - struct proc *p; -#if 0 - register struct msgrcv_args *uap; -#else - void *uap; -#endif -{ - return(EOPNOTSUPP); -}; --- xnu-517.3.7/bsd/kern/sysv_msg.c Fri Dec 19 17:36:53 2003 +++ xnu-517.3.7.patched/bsd/kern/sysv_msg.c Mon Feb 23 08:55:27 2004 @@ -40,40 +40,52 @@ * * This software is provided ``AS IS'' without any warranties of any kind. */ +/* + * Alex Scotti modified the implementation for Darwin. 2/2004 + */ #include #include -#include #include #include #include -#include +#include +#include + +#include +#include #include +#include +#if 0 static void msginit __P((void *)); SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL) +#endif #define MSG_DEBUG #undef MSG_DEBUG_OK #ifndef _SYS_SYSPROTO_H_ struct msgctl_args; -int msgctl __P((struct proc *p, struct msgctl_args *uap)); +int msgctl __P((struct proc *p, struct msgctl_args *uap, int *retval)); struct msgget_args; -int msgget __P((struct proc *p, struct msgget_args *uap)); +int msgget __P((struct proc *p, struct msgget_args *uap, int *retval)); struct msgsnd_args; -int msgsnd __P((struct proc *p, struct msgsnd_args *uap)); +int msgsnd __P((struct proc *p, struct msgsnd_args *uap, int *retval)); struct msgrcv_args; -int msgrcv __P((struct proc *p, struct msgrcv_args *uap)); +int msgrcv __P((struct proc *p, struct msgrcv_args *uap, int *retval)); #endif static void msg_freehdr __P((struct msg *msghdr)); +typedef int sy_call_t __P((struct proc *, void *, int *)); + /* XXX casting to (sy_call_t *) is bogus, as usual. */ static sy_call_t *msgcalls[] = { (sy_call_t *)msgctl, (sy_call_t *)msgget, (sy_call_t *)msgsnd, (sy_call_t *)msgrcv }; +static int msg_inited = 0; /* has this code been initialized yet? */ static int nfree_msgmaps; /* # of free map entries */ static short free_msgmaps; /* head of linked list of free map entries */ static struct msg *free_msghdrs; /* list of free msg headers */ @@ -82,6 +94,18 @@ struct msg *msghdrs; /* MSGTQL msg headers */ struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ +#ifdef __APPLE_API_PRIVATE +struct msginfo msginfo = + { + -1, /* MSGMAX */ + -1, /* MSGMNI */ + -1, /* MSGMNB */ + -1, /* MSGTQL */ + -1, /* MSGSSZ */ + -1 /* MSGSEG */ + }; +#endif /* __APPLE_API_PRIVATE */ + void msginit(dummy) void *dummy; @@ -94,6 +118,25 @@ * or greater than about 256 so ... */ + msgpool = _MALLOC(msginfo.msgmax, M_SYSVMSG, M_WAITOK); + if (msgpool == NULL) + panic("msgpool is NULL"); + + msgmaps =_MALLOC(sizeof(struct msgmap) * msginfo.msgseg, M_SYSVMSG, + M_WAITOK); + if (msgmaps == NULL) + panic("msgmaps is NULL"); + + msghdrs = _MALLOC(sizeof(struct msg) * msginfo.msgtql, M_SYSVMSG, + M_WAITOK); + if (msghdrs == NULL) + panic("msghdrs is NULL"); + + msqids =_MALLOC(sizeof(struct msqid_ds) * msginfo.msgmni, M_SYSVMSG, + M_WAITOK); + if (msqids == NULL) + panic("msqids is NULL"); + i = 8; while (i < 1024 && i != msginfo.msgssz) i <<= 1; @@ -137,13 +180,21 @@ msqids[i].msg_qbytes = 0; /* implies entry is available */ msqids[i].msg_perm.seq = 0; /* reset to a known value */ } + msg_inited = 1; } +struct msgsys_args { + u_int which; + int a2; + int a3; + int a4; +}; + /* * Entry point for all MSG calls */ int -msgsys(p, uap) + msgsys(p, uap, retval) struct proc *p; /* XXX actually varargs. */ struct msgsys_args /* { @@ -154,11 +205,12 @@ int a5; int a6; } */ *uap; + register_t *retval; { if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0])) return (EINVAL); - return ((*msgcalls[uap->which])(p, &uap->a2)); + return ((*msgcalls[uap->which])(p, &uap->a2, retval)); } static void @@ -194,9 +246,10 @@ #endif int -msgctl(p, uap) + msgctl(p, uap, retval) struct proc *p; register struct msgctl_args *uap; + register_t *retval; { int msqid = uap->msqid; int cmd = uap->cmd; @@ -210,6 +263,9 @@ printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr); #endif + if (!msg_inited) + return EINVAL; + AUDIT_ARG(svipc_cmd, cmd); AUDIT_ARG(svipc_id, msqid); msqid = IPCID_TO_IX(msqid); @@ -322,7 +378,7 @@ } if (eval == 0) - p->p_retval[0] = rval; + *retval = rval; return(eval); } @@ -334,9 +390,10 @@ #endif int -msgget(p, uap) + msgget(p, uap, retval) struct proc *p; register struct msgget_args *uap; + register_t *retval; { int msqid, eval; int key = uap->key; @@ -348,6 +405,9 @@ printf("msgget(0x%x, 0%o)\n", key, msgflg); #endif + if (!msg_inited) + return EINVAL; + if (key != IPC_PRIVATE) { for (msqid = 0; msqid < msginfo.msgmni; msqid++) { msqptr = &msqids[msqid]; @@ -428,8 +488,8 @@ found: /* Construct the unique msqid */ - p->p_retval[0] = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); - AUDIT_ARG(svipc_id, p->p_retval[0]); + *retval = IXSEQ_TO_IPCID(msqid, msqptr->msg_perm); + AUDIT_ARG(svipc_id, *retval); return(0); } @@ -443,9 +503,10 @@ #endif int -msgsnd(p, uap) + msgsnd(p, uap, retval) struct proc *p; register struct msgsnd_args *uap; + register_t *retval; { int msqid = uap->msqid; void *user_msgp = uap->msgp; @@ -462,6 +523,9 @@ msgflg); #endif + if (!msg_inited) + return EINVAL; + AUDIT_ARG(svipc_id, msqid); msqid = IPCID_TO_IX(msqid); @@ -765,7 +829,7 @@ msqptr->msg_stime = time_second; wakeup((caddr_t)msqptr); - p->p_retval[0] = 0; + *retval = 0; return(0); } @@ -780,9 +844,10 @@ #endif int -msgrcv(p, uap) + msgrcv(p, uap, retval) struct proc *p; register struct msgrcv_args *uap; + register_t *retval; { int msqid = uap->msqid; void *user_msgp = uap->msgp; @@ -801,6 +866,9 @@ msgsz, msgtyp, msgflg); #endif + if (!msg_inited) + return EINVAL; + AUDIT_ARG(svipc_id, msqid); msqid = IPCID_TO_IX(msqid); @@ -1053,6 +1121,57 @@ msg_freehdr(msghdr); wakeup((caddr_t)msqptr); - p->p_retval[0] = msgsz; + *retval = msgsz; + return(0); +} + +/* (struct sysctl_oid *oidp, void *arg1, int arg2, \ + struct sysctl_req *req) */ +static int +sysctl_msginfo SYSCTL_HANDLER_ARGS +{ + int error = 0; + + error = SYSCTL_OUT(req, arg1, sizeof(int)); + if (error || !req->newptr) + return(error); + + /* Set the values only if not already initialised */ + if (!msg_inited) { + if (error = SYSCTL_IN(req, arg1, sizeof(int))) + return(error); + + /* Initialize only when all values are set */ + if ((msginfo.msgmax != -1) && + (msginfo.msgmni != -1) && + (msginfo.msgmnb != -1) && + (msginfo.msgtql != -1) && + (msginfo.msgssz != -1) && + (msginfo.msgseg != -1)) { + msginit(NULL); + } + } return(0); } + + +extern struct sysctl_oid_list sysctl__kern_sysv_children; + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGMAX, msgmax, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgmax, 0, sysctl_msginfo, "I", "msgmax"); + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGMNI, msgmni, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgmni, 0, sysctl_msginfo, "I", "msgmni"); + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGMNB, msgmnb, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgmnb, 0, sysctl_msginfo, "I", "msgmnb"); + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGTQL, msgtql, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgtql, 0, sysctl_msginfo, "I", "msgtql"); + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGSSZ, msgssz, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgssz, 0, sysctl_msginfo, "I", "msgssz"); + +SYSCTL_PROC(_kern_sysv, KSYSV_MSGSEG, msgseg, CTLTYPE_INT | CTLFLAG_RW, + &msginfo.msgseg, 0, sysctl_msginfo, "I", "msgseg"); + --- xnu-517.3.7/bsd/kern/sysctl_init.c Fri Dec 19 17:36:53 2003 +++ xnu-517.3.7.patched/bsd/kern/sysctl_init.c Thu Feb 19 07:40:12 2004 @@ -94,6 +94,13 @@ extern struct sysctl_oid sysctl__kern_sysv_semmsl; extern struct sysctl_oid sysctl__kern_sysv_semume; +extern struct sysctl_oid sysctl__kern_sysv_msgmax; +extern struct sysctl_oid sysctl__kern_sysv_msgmni; +extern struct sysctl_oid sysctl__kern_sysv_msgmnb; +extern struct sysctl_oid sysctl__kern_sysv_msgtql; +extern struct sysctl_oid sysctl__kern_sysv_msgssz; +extern struct sysctl_oid sysctl__kern_sysv_msgseg; + extern struct sysctl_oid sysctl__kern_dummy; extern struct sysctl_oid sysctl__kern_ipc_maxsockbuf; extern struct sysctl_oid sysctl__kern_ipc_nmbclusters; @@ -450,6 +457,12 @@ ,&sysctl__kern_sysv_semmnu ,&sysctl__kern_sysv_semmsl ,&sysctl__kern_sysv_semume + ,&sysctl__kern_sysv_msgmax + ,&sysctl__kern_sysv_msgmni + ,&sysctl__kern_sysv_msgmnb + ,&sysctl__kern_sysv_msgtql + ,&sysctl__kern_sysv_msgssz + ,&sysctl__kern_sysv_msgseg ,&sysctl__kern_dummy ,&sysctl__kern_ipc_maxsockbuf ,&sysctl__kern_ipc_nmbclusters --- xnu-517.3.7/bsd/sys/sysctl.h Fri Dec 19 17:37:23 2003 +++ xnu-517.3.7.patched/bsd/sys/sysctl.h Mon Feb 23 09:47:46 2004 @@ -380,6 +380,13 @@ #define KSYSV_SEMMNU 8 /* int: max num of undo structures in system */ #define KSYSV_SEMMSL 9 /* int: max num of semaphores per id */ #define KSYSV_SEMUNE 10 /* int: max num of undo entries per process */ +#define KSYSV_MSGMAX 11 /* int: max size of a message (bytes) */ +#define KSYSV_MSGMNI 12 /* int: max num of message queue ids in system */ +#define KSYSV_MSGMNB 13 /* int: max num of bytes on a message queue */ +#define KSYSV_MSGTQL 14 /* int: max num of concurrent messages in system */ +#define KSYSV_MSGSSZ 15 /* int: size of a message segment (bytes) */ +#define KSYSV_MSGSEG 16 /* int: max num of msg segments in system */ + #define CTL_KERN_NAMES { \ --- xnu-517.3.7/bsd/sys/malloc.h Fri Dec 19 17:37:23 2003 +++ xnu-517.3.7.patched/bsd/sys/malloc.h Mon Feb 23 08:26:29 2004 @@ -172,8 +172,9 @@ #define M_JNL_TR 92 /* Journaling: "struct transaction" */ #define M_SPECINFO 93 /* special file node */ #define M_KQUEUE 94 /* kqueue */ +#define M_SYSVMSG 95 /* SVID compatible message queues */ -#define M_LAST 95 /* Must be last type + 1 */ +#define M_LAST 96 /* Must be last type + 1 */ /* Strings corresponding to types of memory */ /* Must be in synch with the #defines above */ @@ -272,7 +273,8 @@ "Journal", /* 91 M_JNL_JNL */\ "Transaction", /* 92 M_JNL_TR */\ "specinfo", /* 93 M_SPECINFO */\ - "kqueue" /* 94 M_KQUEUE */\ + "kqueue", /* 94 M_KQUEUE */ \ + "sysv msgq" /* 95 M_SYSVMSG */ \ } struct kmemstats { --- xnu-517.3.7/bsd/conf/files Fri Dec 19 17:22:53 2003 +++ xnu-517.3.7.patched/bsd/conf/files Wed Feb 18 16:46:08 2004 @@ -512,6 +512,7 @@ bsd/kern/sysv_ipc.c standard bsd/kern/sysv_shm.c standard bsd/kern/sysv_sem.c standard +bsd/kern/sysv_msg.c standard bsd/kern/mach_fat.c standard bsd/kern/mach_header.c standard bsd/kern/mach_loader.c standard