]> sourceware.org Git - glibc.git/blame - mach/msgserver.c
Update.
[glibc.git] / mach / msgserver.c
CommitLineData
6d52618b
UD
1/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
28f540f4 3
6d52618b
UD
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
28f540f4 8
6d52618b
UD
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
28f540f4 13
6d52618b
UD
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
28f540f4
RM
18
19/* Based on CMU's mach_msg_server.c revision 2.4 of 91/05/14, and thus
20 under the following copyright. Rewritten by Roland McGrath (FSF)
21 93/12/06 to use stack space instead of malloc, and to handle
22 large messages with MACH_RCV_LARGE. */
23
19c3f208 24/*
28f540f4
RM
25 * Mach Operating System
26 * Copyright (c) 1991,1990 Carnegie Mellon University
27 * All Rights Reserved.
19c3f208 28 *
28f540f4
RM
29 * Permission to use, copy, modify and distribute this software and its
30 * documentation is hereby granted, provided that both the copyright
31 * notice and this permission notice appear in all copies of the
32 * software, derivative works or modified versions, and any portions
33 * thereof, and that both notices appear in supporting documentation.
19c3f208 34 *
28f540f4
RM
35 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
36 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
37 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19c3f208 38 *
28f540f4 39 * Carnegie Mellon requests users of this software to return to
19c3f208 40 *
28f540f4
RM
41 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
42 * School of Computer Science
43 * Carnegie Mellon University
44 * Pittsburgh PA 15213-3890
19c3f208 45 *
28f540f4
RM
46 * any improvements or extensions that they make and grant Carnegie Mellon
47 * the rights to redistribute these changes.
48 */
49/*
50 * HISTORY
51 * $Log$
6d52618b
UD
52 * Revision 1.5 1996/12/20 01:32:35 drepper
53 * Update from main archive 961219
54 *
55 * Revision 1.5 1996/12/19 20:23:45 drepper
56 * Spelling corrections.
57 *
19c3f208
RM
58 * Revision 1.4 1996/01/29 15:44:23 roland
59 * Declare DEMUX arg with prototype.
60 *
61 * Revision 1.3 1995/01/21 15:00:57 roland
28f540f4
RM
62 * Converted to use weak aliases with macros from libc-symbols.h.
63 *
64 * Revision 1.2 1994/10/10 07:20:14 roland
65 * Increase default MAX_SIZE to two pages.
66 *
67 * Revision 1.1 1993/12/06 23:25:25 roland
68 * entered into RCS
69 *
70 * Revision 2.4 91/05/14 17:53:22 mrt
71 * Correcting copyright
19c3f208 72 *
28f540f4
RM
73 * Revision 2.3 91/02/14 14:17:47 mrt
74 * Added new Mach copyright
75 * [91/02/13 12:44:20 mrt]
19c3f208 76 *
28f540f4
RM
77 * Revision 2.2 90/08/06 17:23:58 rpd
78 * Created.
19c3f208 79 *
28f540f4
RM
80 */
81
82
83#include <mach.h>
84#include <mach/mig_errors.h>
85#include <stdlib.h> /* For malloc and free. */
86
87mach_msg_return_t
88__mach_msg_server_timeout (boolean_t (*demux) (mach_msg_header_t *request,
89 mach_msg_header_t *reply),
90 mach_msg_size_t max_size,
91 mach_port_t rcv_name,
92 mach_msg_option_t option,
93 mach_msg_timeout_t timeout)
94{
95 register mig_reply_header_t *request, *reply;
96 register mach_msg_return_t mr;
97
98 if (max_size == 0)
99 {
100 option |= MACH_RCV_LARGE;
101 max_size = 2 * __vm_page_size; /* Generic. Good? XXX */
102 }
103
104 request = __alloca (max_size);
105 reply = __alloca (max_size);
106
107 while (1)
108 {
109 get_request:
110 mr = __mach_msg (&request->Head, MACH_RCV_MSG|option,
111 0, max_size, rcv_name,
112 timeout, MACH_PORT_NULL);
113 while (mr == MACH_MSG_SUCCESS)
114 {
115 /* We have a request message.
116 Pass it to DEMUX for processing. */
117
118 (void) (*demux) (&request->Head, &reply->Head);
119
120 switch (reply->RetCode)
121 {
122 case KERN_SUCCESS:
123 /* Hunky dory. */
124 break;
125
126 case MIG_NO_REPLY:
127 /* The server function wanted no reply sent.
128 Loop for another request. */
129 goto get_request;
130
131 default:
132 /* Some error; destroy the request message to release any
133 port rights or VM it holds. Don't destroy the reply port
134 right, so we can send an error message. */
135 request->Head.msgh_remote_port = MACH_PORT_NULL;
136 __mach_msg_destroy (&request->Head);
137 break;
138 }
139
140 if (reply->Head.msgh_remote_port == MACH_PORT_NULL)
141 {
142 /* No reply port, so destroy the reply. */
143 if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
144 __mach_msg_destroy (&reply->Head);
145 goto get_request;
146 }
147
148 /* Send the reply and the get next request. */
149
150 {
151 /* Swap the request and reply buffers. mach_msg will read the
152 reply message from the buffer we pass and write the new
153 request message to the same buffer. */
154 void *tmp = request;
155 request = reply;
156 reply = tmp;
157 }
158
159 mr = __mach_msg (&request->Head,
160 MACH_SEND_MSG|MACH_RCV_MSG|option,
161 request->Head.msgh_size, max_size, rcv_name,
162 timeout, MACH_PORT_NULL);
163 }
164
165 /* A message error occurred. */
166
167 switch (mr)
168 {
169 case MACH_RCV_TOO_LARGE:
170 /* The request message is larger than MAX_SIZE, and has not
6d52618b 171 been dequeued. The message header has the actual size of
28f540f4
RM
172 the message. We recurse here in hopes that the compiler
173 will optimize the tail-call and allocate some more stack
174 space instead of way too much. */
175 return __mach_msg_server_timeout (demux, request->Head.msgh_size,
176 rcv_name, option, timeout);
177
178 case MACH_SEND_INVALID_DEST:
179 /* The reply can't be delivered, so destroy it. This error
6d52618b 180 indicates only that the requester went away, so we
28f540f4
RM
181 continue and get the next request. */
182 __mach_msg_destroy (&request->Head);
183 break;
184
185 default:
186 /* Some other form of lossage; return to caller. */
187 return mr;
188 }
189 }
190}
191weak_alias (__mach_msg_server_timeout, mach_msg_server_timeout)
192
193mach_msg_return_t
194__mach_msg_server (demux, max_size, rcv_name)
19c3f208 195 boolean_t (*demux) (mach_msg_header_t *in, mach_msg_header_t *out);
28f540f4
RM
196 mach_msg_size_t max_size;
197 mach_port_t rcv_name;
198{
199 return __mach_msg_server_timeout (demux, max_size, rcv_name,
200 MACH_MSG_OPTION_NONE,
201 MACH_MSG_TIMEOUT_NONE);
202}
203weak_alias (__mach_msg_server, mach_msg_server)
This page took 0.159654 seconds and 5 git commands to generate.