/* * msgget system call. */ static int msgget(key_t key, int msgflg) { kmsqid_t *qp; kmutex_t *lock; int id, error; int ii; proc_t *pp = curproc; top: if (error = ipc_get(msq_svc, key, msgflg, (kipc_perm_t **)&qp, &lock)) return (set_errno(error)); if (IPC_FREE(&qp->msg_perm)) { mutex_exit(lock); mutex_exit(&pp->p_lock); list_create(&qp->msg_list, sizeof (struct msg), offsetof(struct msg, msg_node)); qp->msg_qnum = 0; qp->msg_lspid = qp->msg_lrpid = 0; qp->msg_stime = qp->msg_rtime = 0; qp->msg_ctime = gethrestime_sec(); qp->msg_ngt_cnt = 0; qp->msg_neg_copy = 0; for (ii = 0; ii <= MSG_MAX_QNUM; ii++) { list_create(&qp->msg_wait_snd[ii], sizeof (msgq_wakeup_t), offsetof(msgq_wakeup_t, msgw_list)); list_create(&qp->msg_wait_snd_ngt[ii], sizeof (msgq_wakeup_t), offsetof(msgq_wakeup_t, msgw_list)); } /* * The proper initialization of msg_lowest_type is to the * highest possible value. By doing this we guarantee that * when the first send happens, the lowest type will be set * properly. */ qp->msg_lowest_type = -1; list_create(&qp->msg_cpy_block, sizeof (msgq_wakeup_t), offsetof(msgq_wakeup_t, msgw_list)); qp->msg_fnd_sndr = &msg_fnd_sndr[0]; qp->msg_fnd_rdr = &msg_fnd_rdr[0]; qp->msg_rcv_cnt = 0; qp->msg_snd_cnt = 0; if (error = ipc_commit_begin(msq_svc, key, msgflg, (kipc_perm_t *)qp)) { if (error == EAGAIN) goto top; return (set_errno(error)); } qp->msg_qbytes = rctl_enforced_value(rc_process_msgmnb, pp->p_rctls, pp); qp->msg_qmax = rctl_enforced_value(rc_process_msgtql, pp->p_rctls, pp); lock = ipc_commit_end(msq_svc, &qp->msg_perm); }
/* * semget - Semget system call. */ static int semget(key_t key, int nsems, int semflg) { ksemid_t *sp; kmutex_t *lock; int id, error; proc_t *pp = curproc; top: if (error = ipc_get(sem_svc, key, semflg, (kipc_perm_t **)&sp, &lock)) return (set_errno(error)); if (!IPC_FREE(&sp->sem_perm)) { /* * A semaphore with the requested key exists. */ if (!((nsems >= 0) && (nsems <= sp->sem_nsems))) { mutex_exit(lock); return (set_errno(EINVAL)); } } else { /* * This is a new semaphore set. Finish initialization. */ if (nsems <= 0 || (rctl_test(rc_process_semmsl, pp->p_rctls, pp, nsems, RCA_SAFE) & RCT_DENY)) { mutex_exit(lock); mutex_exit(&pp->p_lock); ipc_cleanup(sem_svc, (kipc_perm_t *)sp); return (set_errno(EINVAL)); } mutex_exit(lock); mutex_exit(&pp->p_lock); /* * We round the allocation up to coherency granularity * so that multiple semaphore allocations won't result * in the false sharing of their sem structures. */ sp->sem_base = kmem_zalloc(P2ROUNDUP(nsems * sizeof (struct sem), 64), KM_SLEEP); sp->sem_binary = (nsems == 1); sp->sem_nsems = (ushort_t)nsems; sp->sem_ctime = gethrestime_sec(); sp->sem_otime = 0; list_create(&sp->sem_undos, sizeof (struct sem_undo), offsetof(struct sem_undo, un_list)); if (error = ipc_commit_begin(sem_svc, key, semflg, (kipc_perm_t *)sp)) { if (error == EAGAIN) goto top; return (set_errno(error)); } sp->sem_maxops = rctl_enforced_value(rc_process_semopm, pp->p_rctls, pp); if (rctl_test(rc_process_semmsl, pp->p_rctls, pp, nsems, RCA_SAFE) & RCT_DENY) { ipc_cleanup(sem_svc, (kipc_perm_t *)sp); return (set_errno(EINVAL)); } lock = ipc_commit_end(sem_svc, &sp->sem_perm); } if (audit_active) audit_ipcget(AT_IPC_SEM, (void *)sp); id = sp->sem_perm.ipc_id; mutex_exit(lock); return (id); }