usr/src/uts/common/os/msg.c
author jpk
Fri, 24 Mar 2006 12:29:20 -0800
changeset 1676 37f4a3e2bd99
parent 0 68f95e015346
child 2565 4ca8919fcdc0
permissions -rw-r--r--
PSARC/2002/762 Layered Trusted Solaris PSARC/2005/060 TSNET: Trusted Networking with Security Labels PSARC/2005/259 Layered Trusted Solaris Label Interfaces PSARC/2005/573 Solaris Trusted Extensions for Printing PSARC/2005/691 Trusted Extensions for Device Allocation PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling PSARC/2006/009 Labeled Auditing PSARC/2006/155 Trusted Extensions RBAC Changes PSARC/2006/191 is_system_labeled 6293271 Zone processes should use zone_kcred instead of kcred 6394554 integrate Solaris Trusted Extensions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * Inter-Process Communication Message Facility.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * See os/ipc.c for a description of common IPC functionality.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * Resource controls
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * -----------------
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 * Control:      project.max-msg-ids (rc_project_msgmni)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 * Description:  Maximum number of message queue ids allowed a project.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *   When msgget() is used to allocate a message queue, one id is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 *   allocated.  If the id allocation doesn't succeed, msgget() fails
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *   and errno is set to ENOSPC.  Upon successful msgctl(, IPC_RMID)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *   the id is deallocated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * Control:      process.max-msg-qbytes (rc_process_msgmnb)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 * Description:  Maximum number of bytes of messages on a message queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 *   When msgget() successfully allocates a message queue, the minimum
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 *   enforced value of this limit is used to initialize msg_qbytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 * Control:      process.max-msg-messages (rc_process_msgtql)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * Description:  Maximum number of messages on a message queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 *   When msgget() successfully allocates a message queue, the minimum
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 *   enforced value of this limit is used to initialize a per-queue
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 *   limit on the number of messages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/t_lock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#include <sys/time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/ipc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/ipc_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
#include <sys/msg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
#include <sys/msg_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
#include <sys/list.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
#include <sys/ddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
#include <sys/project.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
#include <sys/syscall.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
#include <sys/policy.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
#include <sys/zone.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
#include <c2/audit.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 * The following tunables are obsolete.  Though for compatibility we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * still read and interpret msginfo_msgmnb, msginfo_msgmni, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 * msginfo_msgtql (see os/project.c and os/rctl_proc.c), the preferred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 * mechanism for administrating the IPC Message facility is through the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * resource controls described at the top of this file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
size_t	msginfo_msgmax = 2048;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
size_t	msginfo_msgmnb = 4096;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
int	msginfo_msgmni = 50;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
int	msginfo_msgtql = 40;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
int	msginfo_msgssz = 8;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
int	msginfo_msgmap = 0;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
ushort_t msginfo_msgseg = 1024;	/* (obsolete) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
extern rctl_hndl_t rc_project_msgmni;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
extern rctl_hndl_t rc_process_msgmnb;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
extern rctl_hndl_t rc_process_msgtql;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
static ipc_service_t *msq_svc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
static zone_key_t msg_zone_key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
static void msg_dtor(kipc_perm_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
static void msg_rmid(kipc_perm_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
static void msg_remove_zone(zoneid_t, void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 * Module linkage information for the kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
static ssize_t msgsys(int opcode, uintptr_t a0, uintptr_t a1, uintptr_t a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
	uintptr_t a4, uintptr_t a5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
static struct sysent ipcmsg_sysent = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
#ifdef	_LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
	SE_ARGC | SE_NOUNLOAD | SE_64RVAL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
	SE_ARGC | SE_NOUNLOAD | SE_32RVAL1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	(int (*)())msgsys
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
#ifdef	_SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
static ssize32_t msgsys32(int opcode, uint32_t a0, uint32_t a1, uint32_t a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	uint32_t a4, uint32_t a5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
static struct sysent ipcmsg_sysent32 = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	6,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	SE_ARGC | SE_NOUNLOAD | SE_32RVAL1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	(int (*)())msgsys32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
#endif	/* _SYSCALL32_IMPL */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
static struct modlsys modlsys = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
	&mod_syscallops, "System V message facility", &ipcmsg_sysent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
static struct modlsys modlsys32 = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	&mod_syscallops32, "32-bit System V message facility", &ipcmsg_sysent32
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
static struct modlinkage modlinkage = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	MODREV_1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	&modlsys,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
#ifdef _SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	&modlsys32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	int result;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	msq_svc = ipcs_create("msqids", rc_project_msgmni, sizeof (kmsqid_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	    msg_dtor, msg_rmid, AT_IPC_MSG,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	    offsetof(kproject_data_t, kpd_msgmni));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	zone_key_create(&msg_zone_key, NULL, msg_remove_zone, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	if ((result = mod_install(&modlinkage)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	(void) zone_key_delete(msg_zone_key);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	ipcs_destroy(msq_svc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	return (result);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
_fini(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	return (EBUSY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
_info(struct modinfo *modinfop)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	return (mod_info(&modlinkage, modinfop));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
msg_dtor(kipc_perm_t *perm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	kmsqid_t *qp = (kmsqid_t *)perm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	ASSERT(qp->msg_rcv_cnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	ASSERT(qp->msg_snd_cnt == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
	ASSERT(qp->msg_cbytes == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
	list_destroy(&qp->msg_list);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
#define	msg_hold(mp)	(mp)->msg_copycnt++
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
 * msg_rele - decrement the reference count on the message.  When count
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
 * reaches zero, free message header and contents.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
msg_rele(struct msg *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	ASSERT(mp->msg_copycnt > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	if (mp->msg_copycnt-- == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
		if (mp->msg_addr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			kmem_free(mp->msg_addr, mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
		kmem_free(mp, sizeof (struct msg));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
 * msgunlink - Unlink msg from queue, decrement byte count and wake up anyone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
 * waiting for free bytes on queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
 * Called with queue locked.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
msgunlink(kmsqid_t *qp, struct msg *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	list_remove(&qp->msg_list, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	qp->msg_qnum--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	qp->msg_cbytes -= mp->msg_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	msg_rele(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	/* Wake up waiting writers */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	if (qp->msg_snd_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		cv_broadcast(&qp->msg_snd_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
msg_rmid(kipc_perm_t *perm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	kmsqid_t *qp = (kmsqid_t *)perm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	struct msg *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	while ((mp = list_head(&qp->msg_list)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
		msgunlink(qp, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	ASSERT(qp->msg_cbytes == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	if (qp->msg_rcv_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
		cv_broadcast(&qp->msg_rcv_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	if (qp->msg_snd_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
		cv_broadcast(&qp->msg_snd_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
 * msgctl system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
 * gets q lock (via ipc_lookup), releases before return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
 * may call users of msg_lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
msgctl(int msgid, int cmd, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	STRUCT_DECL(msqid_ds, ds);		/* SVR4 queue work area */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	kmsqid_t		*qp;		/* ptr to associated q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	int			error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	struct	cred		*cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	model_t	mdl = get_udatamodel();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	struct msqid_ds64	ds64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	kmutex_t		*lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	proc_t			*pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	STRUCT_INIT(ds, mdl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	cr = CRED();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	 * Perform pre- or non-lookup actions (e.g. copyins, RMID).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	case IPC_SET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		if (copyin(arg, STRUCT_BUF(ds), STRUCT_SIZE(ds)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	case IPC_SET64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
		if (copyin(arg, &ds64, sizeof (struct msqid_ds64)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	case IPC_RMID:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		if (error = ipc_rmid(msq_svc, msgid, cr))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
			return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
	 * get msqid_ds for this msgid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	if ((lock = ipc_lookup(msq_svc, msgid, (kipc_perm_t **)&qp)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	case IPC_SET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
		if (STRUCT_FGET(ds, msg_qbytes) > qp->msg_qbytes &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		    secpolicy_ipc_config(cr) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
			return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
		if (error = ipcperm_set(msq_svc, cr, &qp->msg_perm,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
		    &STRUCT_BUF(ds)->msg_perm, mdl)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
			return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
		qp->msg_qbytes = STRUCT_FGET(ds, msg_qbytes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
		qp->msg_ctime = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	case IPC_STAT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
		if (error = ipcperm_access(&qp->msg_perm, MSG_R, cr)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
			return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
		if (qp->msg_rcv_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
			qp->msg_perm.ipc_mode |= MSG_RWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
		if (qp->msg_snd_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
			qp->msg_perm.ipc_mode |= MSG_WWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
		ipcperm_stat(&STRUCT_BUF(ds)->msg_perm, &qp->msg_perm, mdl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
		qp->msg_perm.ipc_mode &= ~(MSG_RWAIT|MSG_WWAIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
		STRUCT_FSETP(ds, msg_first, NULL); 	/* kernel addr */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
		STRUCT_FSETP(ds, msg_last, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
		STRUCT_FSET(ds, msg_cbytes, qp->msg_cbytes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		STRUCT_FSET(ds, msg_qnum, qp->msg_qnum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
		STRUCT_FSET(ds, msg_qbytes, qp->msg_qbytes);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
		STRUCT_FSET(ds, msg_lspid, qp->msg_lspid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
		STRUCT_FSET(ds, msg_lrpid, qp->msg_lrpid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
		STRUCT_FSET(ds, msg_stime, qp->msg_stime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
		STRUCT_FSET(ds, msg_rtime, qp->msg_rtime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
		STRUCT_FSET(ds, msg_ctime, qp->msg_ctime);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	case IPC_SET64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
		mutex_enter(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
		if ((ds64.msgx_qbytes > qp->msg_qbytes) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
		    secpolicy_ipc_config(cr) != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		    rctl_test(rc_process_msgmnb, pp->p_rctls, pp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
		    ds64.msgx_qbytes, RCA_SAFE) & RCT_DENY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
			mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
			return (set_errno(EPERM));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
		if (error = ipcperm_set64(msq_svc, cr, &qp->msg_perm,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
		    &ds64.msgx_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
			return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		qp->msg_qbytes = ds64.msgx_qbytes;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		qp->msg_ctime = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	case IPC_STAT64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
		if (qp->msg_rcv_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
			qp->msg_perm.ipc_mode |= MSG_RWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		if (qp->msg_snd_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
			qp->msg_perm.ipc_mode |= MSG_WWAIT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		ipcperm_stat64(&ds64.msgx_perm, &qp->msg_perm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
		qp->msg_perm.ipc_mode &= ~(MSG_RWAIT|MSG_WWAIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
		ds64.msgx_cbytes = qp->msg_cbytes;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		ds64.msgx_qnum = qp->msg_qnum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
		ds64.msgx_qbytes = qp->msg_qbytes;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		ds64.msgx_lspid = qp->msg_lspid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		ds64.msgx_lrpid = qp->msg_lrpid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		ds64.msgx_stime = qp->msg_stime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		ds64.msgx_rtime = qp->msg_rtime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		ds64.msgx_ctime = qp->msg_ctime;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
		mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
	 * Do copyout last (after releasing mutex).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	switch (cmd) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	case IPC_STAT:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		if (copyout(STRUCT_BUF(ds), arg, STRUCT_SIZE(ds)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
	case IPC_STAT64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		if (copyout(&ds64, arg, sizeof (struct msqid_ds64)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
 * Remove all message queues associated with a given zone.  Called by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
 * zone_shutdown when the zone is halted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
/*ARGSUSED1*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
msg_remove_zone(zoneid_t zoneid, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
	ipc_remove_zone(msq_svc, zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
 * msgget system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
msgget(key_t key, int msgflg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	kmsqid_t	*qp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	kmutex_t	*lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	int		id, error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	proc_t		*pp = curproc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
top:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	if (error = ipc_get(msq_svc, key, msgflg, (kipc_perm_t **)&qp, &lock))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	if (IPC_FREE(&qp->msg_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
		mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
		mutex_exit(&pp->p_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
		list_create(&qp->msg_list, sizeof (struct msg),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
		    offsetof(struct msg, msg_node));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
		qp->msg_qnum = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
		qp->msg_lspid = qp->msg_lrpid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
		qp->msg_stime = qp->msg_rtime = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
		qp->msg_ctime = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
		qp->msg_rcv_cnt = qp->msg_snd_cnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
		if (error = ipc_commit_begin(msq_svc, key, msgflg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
		    (kipc_perm_t *)qp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
			if (error == EAGAIN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
				goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
			return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
		qp->msg_qbytes = rctl_enforced_value(rc_process_msgmnb,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
		    pp->p_rctls, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
		qp->msg_qmax = rctl_enforced_value(rc_process_msgtql,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
		    pp->p_rctls, pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		lock = ipc_commit_end(msq_svc, &qp->msg_perm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
#ifdef C2_AUDIT
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
	if (audit_active)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
		audit_ipcget(AT_IPC_MSG, (void *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	id = qp->msg_perm.ipc_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	return (id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
 * msgrcv system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
static ssize_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
msgrcv(int msqid, struct ipcmsgbuf *msgp, size_t msgsz, long msgtyp, int msgflg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	struct msg	*mp;	/* ptr to msg on q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
	struct msg	*smp;	/* ptr to best msg on q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	kmsqid_t	*qp;	/* ptr to associated q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	kmutex_t	*lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	size_t		xtsz;	/* transfer byte count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	int		error = 0, copyerror = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
	int		cvres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	STRUCT_HANDLE(ipcmsgbuf, umsgp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	model_t		mdl = get_udatamodel();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	CPU_STATS_ADDQ(CPU, sys, msg, 1);	/* bump msg send/rcv count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	STRUCT_SET_HANDLE(umsgp, mdl, msgp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
	if ((lock = ipc_lookup(msq_svc, msqid, (kipc_perm_t **)&qp)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
		return ((ssize_t)set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	ipc_hold(msq_svc, (kipc_perm_t *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	if (error = ipcperm_access(&qp->msg_perm, MSG_R, CRED()))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
findmsg:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	smp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	mp = list_head(&qp->msg_list);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	if (msgtyp == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
		smp = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
		for (; mp; mp = list_next(&qp->msg_list, mp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
			if (msgtyp > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
				if (msgtyp != mp->msg_type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
				smp = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
			if (mp->msg_type <= -msgtyp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
				if (smp && smp->msg_type <= mp->msg_type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
				smp = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	if (smp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
		 * Message found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
		if ((smp->msg_flags & MSG_RCVCOPY) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
			 * No one else is copying this message. Copy it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
			if (msgsz < smp->msg_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
				if ((msgflg & MSG_NOERROR) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
					error = E2BIG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
					goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
					xtsz = msgsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
				xtsz = smp->msg_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
			 * Mark message as being copied out. Release mutex
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
			 * while copying out.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
			ASSERT((smp->msg_flags & MSG_RCVCOPY) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
			smp->msg_flags |= MSG_RCVCOPY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
			msg_hold(smp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
			mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
			if (mdl == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
				copyerror = copyout(&smp->msg_type, msgp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
				    sizeof (smp->msg_type));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
				 * 32-bit callers need an imploded msg type.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
				int32_t	msg_type32 = smp->msg_type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
				copyerror = copyout(&msg_type32, msgp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
				    sizeof (msg_type32));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
			if (copyerror == 0 && xtsz)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
				copyerror = copyout(smp->msg_addr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
				    STRUCT_FADDR(umsgp, mtext), xtsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
			 * Reclaim mutex, make sure queue still exists,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
			 * and remove message.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
			lock = ipc_lock(msq_svc, qp->msg_perm.ipc_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
			ASSERT(smp->msg_flags & MSG_RCVCOPY);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
			smp->msg_flags &= ~MSG_RCVCOPY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
			msg_rele(smp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
			if (IPC_FREE(&qp->msg_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
				error = EIDRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
				goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
			cv_broadcast(&qp->msg_rcv_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
			if (copyerror) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
				goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
			qp->msg_lrpid = ttoproc(curthread)->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
			qp->msg_rtime = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			msgunlink(qp, smp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
		 * No message found.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
		if (msgflg & IPC_NOWAIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
			error = ENOMSG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
			goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	/* Wait for new message */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	qp->msg_rcv_cnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	cvres = cv_wait_sig(&qp->msg_rcv_cv, lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	lock = ipc_relock(msq_svc, qp->msg_perm.ipc_id, lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	qp->msg_rcv_cnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	if (IPC_FREE(&qp->msg_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
		error = EIDRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
	if (cvres == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
		error = EINTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
		goto msgrcv_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	goto findmsg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
msgrcv_out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
	ipc_rele(msq_svc, (kipc_perm_t *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
		return ((ssize_t)set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	return ((ssize_t)xtsz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
 * msgids system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
msgids(int *buf, uint_t nids, uint_t *pnids)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	int error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
	if (error = ipc_ids(msq_svc, buf, nids, pnids))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
#define	RND(x)		roundup((x), sizeof (size_t))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
#define	RND32(x)	roundup((x), sizeof (size32_t))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
 * msgsnap system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
msgsnap(int msqid, caddr_t buf, size_t bufsz, long msgtyp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
	struct msg	*mp;	/* ptr to msg on q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
	kmsqid_t	*qp;	/* ptr to associated q */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	kmutex_t	*lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
	size_t		size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	size_t		nmsg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
	struct msg	**snaplist;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
	int		error, i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	model_t		mdl = get_udatamodel();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
	STRUCT_DECL(msgsnap_head, head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	STRUCT_DECL(msgsnap_mhead, mhead);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
	STRUCT_INIT(head, mdl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
	STRUCT_INIT(mhead, mdl);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	if (bufsz < STRUCT_SIZE(head))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
	if ((lock = ipc_lookup(msq_svc, msqid, (kipc_perm_t **)&qp)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	if (error = ipcperm_access(&qp->msg_perm, MSG_R, CRED())) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
		mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
	ipc_hold(msq_svc, (kipc_perm_t *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	 * First compute the required buffer size and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	 * the number of messages on the queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	size = nmsg = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	for (mp = list_head(&qp->msg_list); mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
	    mp = list_next(&qp->msg_list, mp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		if (msgtyp == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		    (msgtyp > 0 && msgtyp == mp->msg_type) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
		    (msgtyp < 0 && mp->msg_type <= -msgtyp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
			nmsg++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
			if (mdl == DATAMODEL_NATIVE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
				size += RND(mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
				size += RND32(mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	size += STRUCT_SIZE(head) + nmsg * STRUCT_SIZE(mhead);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	if (size > bufsz)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
		nmsg = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
	if (nmsg > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
		 * Mark the messages as being copied.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
		snaplist = (struct msg **)kmem_alloc(nmsg *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
		    sizeof (struct msg *), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
		i = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
		for (mp = list_head(&qp->msg_list); mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
		    mp = list_next(&qp->msg_list, mp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
			if (msgtyp == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
			    (msgtyp > 0 && msgtyp == mp->msg_type) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
			    (msgtyp < 0 && mp->msg_type <= -msgtyp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
				msg_hold(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
				snaplist[i] = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
				i++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
	mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	 * Copy out the buffer header.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
	STRUCT_FSET(head, msgsnap_size, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
	STRUCT_FSET(head, msgsnap_nmsg, nmsg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	if (copyout(STRUCT_BUF(head), buf, STRUCT_SIZE(head)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
	buf += STRUCT_SIZE(head);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
	 * Now copy out the messages one by one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	for (i = 0; i < nmsg; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
		mp = snaplist[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
		if (error == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
			STRUCT_FSET(mhead, msgsnap_mlen, mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
			STRUCT_FSET(mhead, msgsnap_mtype, mp->msg_type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
			if (copyout(STRUCT_BUF(mhead), buf, STRUCT_SIZE(mhead)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
			buf += STRUCT_SIZE(mhead);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
			if (error == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
			    mp->msg_size != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
			    copyout(mp->msg_addr, buf, mp->msg_size))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
				error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
			if (mdl == DATAMODEL_NATIVE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
				buf += RND(mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
				buf += RND32(mp->msg_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
		lock = ipc_lock(msq_svc, qp->msg_perm.ipc_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
		msg_rele(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
		/* Check for msg q deleted or reallocated */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
		if (IPC_FREE(&qp->msg_perm))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
			error = EIDRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
	(void) ipc_lock(msq_svc, qp->msg_perm.ipc_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
	ipc_rele(msq_svc, (kipc_perm_t *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
	if (nmsg > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
		kmem_free(snaplist, nmsg * sizeof (struct msg *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	if (error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
 * msgsnd system call.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
msgsnd(int msqid, struct ipcmsgbuf *msgp, size_t msgsz, int msgflg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	kmsqid_t	*qp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	kmutex_t	*lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
	struct msg	*mp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	long		type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
	int		error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	model_t		mdl = get_udatamodel();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	STRUCT_HANDLE(ipcmsgbuf, umsgp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	CPU_STATS_ADDQ(CPU, sys, msg, 1);	/* bump msg send/rcv count */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
	STRUCT_SET_HANDLE(umsgp, mdl, msgp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	if (mdl == DATAMODEL_NATIVE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
		if (copyin(msgp, &type, sizeof (type)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
		int32_t	type32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
		if (copyin(msgp, &type32, sizeof (type32)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
			return (set_errno(EFAULT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
		type = type32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
	if (type < 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
	if ((lock = ipc_lookup(msq_svc, msqid, (kipc_perm_t **)&qp)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
		return (set_errno(EINVAL));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
	ipc_hold(msq_svc, (kipc_perm_t *)qp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	if (msgsz > qp->msg_qbytes) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
		error = EINVAL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
		goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
	if (error = ipcperm_access(&qp->msg_perm, MSG_W, CRED()))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
		goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
top:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
	 * Allocate space on q, message header, & buffer space.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
	ASSERT(qp->msg_qnum <= qp->msg_qmax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
	while ((msgsz > qp->msg_qbytes - qp->msg_cbytes) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	    (qp->msg_qnum == qp->msg_qmax)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
		int cvres;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		if (msgflg & IPC_NOWAIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
			error = EAGAIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
			goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
		qp->msg_snd_cnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
		cvres = cv_wait_sig(&qp->msg_snd_cv, lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
		lock = ipc_relock(msq_svc, qp->msg_perm.ipc_id, lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
		qp->msg_snd_cnt--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		if (IPC_FREE(&qp->msg_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
			error = EIDRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
			goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		if (cvres == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
			error = EINTR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
			goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
	if (mp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		int failure;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
		mutex_exit(lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
		mp = kmem_zalloc(sizeof (struct msg), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
		mp->msg_addr = kmem_zalloc(msgsz, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
		mp->msg_size = msgsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
		mp->msg_copycnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
		failure = msgsz && (copyin(STRUCT_FADDR(umsgp, mtext),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
		    mp->msg_addr, msgsz) == -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
		lock = ipc_lock(msq_svc, qp->msg_perm.ipc_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
		if (IPC_FREE(&qp->msg_perm)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
			error = EIDRM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
			goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
		if (failure) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
			error = EFAULT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
			goto msgsnd_out;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
		goto top;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	 * Everything is available, put msg on q.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	qp->msg_qnum++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	qp->msg_cbytes += msgsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	qp->msg_lspid = curproc->p_pid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	qp->msg_stime = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	mp->msg_type = type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	mp->msg_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
	list_insert_tail(&qp->msg_list, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	if (qp->msg_rcv_cnt)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
		cv_broadcast(&qp->msg_rcv_cv);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
msgsnd_out:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	ipc_rele(msq_svc, (kipc_perm_t *)qp);	/* drops lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	if (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
		if (mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
			msg_rele(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
		return (set_errno(error));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
 * msgsys - System entry point for msgctl, msgget, msgrcv, and msgsnd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
 * system calls.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
static ssize_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
msgsys(int opcode, uintptr_t a1, uintptr_t a2, uintptr_t a3,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	uintptr_t a4, uintptr_t a5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	ssize_t error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	switch (opcode) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	case MSGGET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
		error = msgget((key_t)a1, (int)a2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	case MSGCTL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
		error = msgctl((int)a1, (int)a2, (void *)a3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	case MSGRCV:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
		error = msgrcv((int)a1, (struct ipcmsgbuf *)a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
		    (size_t)a3, (long)a4, (int)a5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	case MSGSND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
		error = msgsnd((int)a1, (struct ipcmsgbuf *)a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
		    (size_t)a3, (int)a4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
	case MSGIDS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
		error = msgids((int *)a1, (uint_t)a2, (uint_t *)a3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
	case MSGSNAP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
		error = msgsnap((int)a1, (caddr_t)a2, (size_t)a3, (long)a4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		error = set_errno(EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
#ifdef	_SYSCALL32_IMPL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
 * msgsys32 - System entry point for msgctl, msgget, msgrcv, and msgsnd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
 * system calls for 32-bit callers on LP64 kernel.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
static ssize32_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
msgsys32(int opcode, uint32_t a1, uint32_t a2, uint32_t a3,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
	uint32_t a4, uint32_t a5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
	ssize_t error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
	switch (opcode) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
	case MSGGET:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
		error = msgget((key_t)a1, (int)a2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
	case MSGCTL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
		error = msgctl((int)a1, (int)a2, (void *)(uintptr_t)a3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	case MSGRCV:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
		error = msgrcv((int)a1, (struct ipcmsgbuf *)(uintptr_t)a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
		    (size_t)a3, (long)(int32_t)a4, (int)a5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
	case MSGSND:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
		error = msgsnd((int)a1, (struct ipcmsgbuf *)(uintptr_t)a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
		    (size_t)(int32_t)a3, (int)a4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
	case MSGIDS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
		error = msgids((int *)(uintptr_t)a1, (uint_t)a2,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
		    (uint_t *)(uintptr_t)a3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
	case MSGSNAP:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
		error = msgsnap((int)a1, (caddr_t)(uintptr_t)a2, (size_t)a3,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
		    (long)(int32_t)a4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
		error = set_errno(EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
	return (error);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
#endif	/* SYSCALL32_IMPL */