]> git.ipfire.org Git - thirdparty/glibc.git/blame - mach/msgserver.c
* sysdeps/mach/hurd/times.c (__times) [NO_CREATION_TIME]: Don't try
[thirdparty/glibc.git] / mach / msgserver.c
CommitLineData
6c2a1e81 1/* Copyright (C) 1993, 1994, 1995, 1996, 2001 Free Software Foundation, Inc.
6d52618b 2 This file is part of the GNU C Library.
28f540f4 3
6d52618b 4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the 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
41bdb6e2 12 Lesser General Public License for more details.
28f540f4 13
41bdb6e2
AJ
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 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$
61c83c3f
RM
52 * Revision 1.8 2002/02/17 07:13:32 roland
53 * 2002-02-16 Roland McGrath <roland@frob.com>
54 *
55 * * mach/msgserver.c [NDR_CHAR_ASCII] (mig_reply_header_t): #define as
56 * mig_reply_error_t for OSF Mach variant.
57 *
41bdb6e2
AJ
58 * Revision 1.7 2001/07/06 04:55:34 aj
59 * Update to LGPL v2.1.
60 *
6c2a1e81
RM
61 * Revision 1.6 2001/04/09 21:23:38 roland
62 * 2001-04-07 Roland McGrath <roland@frob.com>
63 *
64 * * mach/msgserver.c (__mach_msg_server_timeout): Add an assert.
65 *
6d52618b
UD
66 * Revision 1.5 1996/12/20 01:32:35 drepper
67 * Update from main archive 961219
68 *
69 * Revision 1.5 1996/12/19 20:23:45 drepper
70 * Spelling corrections.
71 *
19c3f208
RM
72 * Revision 1.4 1996/01/29 15:44:23 roland
73 * Declare DEMUX arg with prototype.
74 *
75 * Revision 1.3 1995/01/21 15:00:57 roland
28f540f4
RM
76 * Converted to use weak aliases with macros from libc-symbols.h.
77 *
78 * Revision 1.2 1994/10/10 07:20:14 roland
79 * Increase default MAX_SIZE to two pages.
80 *
81 * Revision 1.1 1993/12/06 23:25:25 roland
82 * entered into RCS
83 *
84 * Revision 2.4 91/05/14 17:53:22 mrt
85 * Correcting copyright
19c3f208 86 *
28f540f4
RM
87 * Revision 2.3 91/02/14 14:17:47 mrt
88 * Added new Mach copyright
89 * [91/02/13 12:44:20 mrt]
19c3f208 90 *
28f540f4
RM
91 * Revision 2.2 90/08/06 17:23:58 rpd
92 * Created.
19c3f208 93 *
28f540f4
RM
94 */
95
96
97#include <mach.h>
98#include <mach/mig_errors.h>
99#include <stdlib.h> /* For malloc and free. */
6c2a1e81 100#include <assert.h>
28f540f4 101
61c83c3f
RM
102#ifdef NDR_CHAR_ASCII /* OSF Mach flavors have different names. */
103# define mig_reply_header_t mig_reply_error_t
104#endif
105
28f540f4
RM
106mach_msg_return_t
107__mach_msg_server_timeout (boolean_t (*demux) (mach_msg_header_t *request,
108 mach_msg_header_t *reply),
109 mach_msg_size_t max_size,
110 mach_port_t rcv_name,
111 mach_msg_option_t option,
112 mach_msg_timeout_t timeout)
113{
114 register mig_reply_header_t *request, *reply;
115 register mach_msg_return_t mr;
116
117 if (max_size == 0)
118 {
119 option |= MACH_RCV_LARGE;
120 max_size = 2 * __vm_page_size; /* Generic. Good? XXX */
121 }
122
123 request = __alloca (max_size);
124 reply = __alloca (max_size);
125
126 while (1)
127 {
128 get_request:
129 mr = __mach_msg (&request->Head, MACH_RCV_MSG|option,
130 0, max_size, rcv_name,
131 timeout, MACH_PORT_NULL);
132 while (mr == MACH_MSG_SUCCESS)
133 {
134 /* We have a request message.
135 Pass it to DEMUX for processing. */
136
137 (void) (*demux) (&request->Head, &reply->Head);
6c2a1e81 138 assert (reply->Head.msgh_size <= max_size);
28f540f4
RM
139
140 switch (reply->RetCode)
141 {
142 case KERN_SUCCESS:
143 /* Hunky dory. */
144 break;
145
146 case MIG_NO_REPLY:
147 /* The server function wanted no reply sent.
148 Loop for another request. */
149 goto get_request;
150
151 default:
152 /* Some error; destroy the request message to release any
153 port rights or VM it holds. Don't destroy the reply port
154 right, so we can send an error message. */
155 request->Head.msgh_remote_port = MACH_PORT_NULL;
156 __mach_msg_destroy (&request->Head);
157 break;
158 }
159
160 if (reply->Head.msgh_remote_port == MACH_PORT_NULL)
161 {
162 /* No reply port, so destroy the reply. */
163 if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
164 __mach_msg_destroy (&reply->Head);
165 goto get_request;
166 }
167
168 /* Send the reply and the get next request. */
169
170 {
171 /* Swap the request and reply buffers. mach_msg will read the
172 reply message from the buffer we pass and write the new
173 request message to the same buffer. */
174 void *tmp = request;
175 request = reply;
176 reply = tmp;
177 }
178
179 mr = __mach_msg (&request->Head,
180 MACH_SEND_MSG|MACH_RCV_MSG|option,
181 request->Head.msgh_size, max_size, rcv_name,
182 timeout, MACH_PORT_NULL);
183 }
184
185 /* A message error occurred. */
186
187 switch (mr)
188 {
189 case MACH_RCV_TOO_LARGE:
190 /* The request message is larger than MAX_SIZE, and has not
6d52618b 191 been dequeued. The message header has the actual size of
28f540f4
RM
192 the message. We recurse here in hopes that the compiler
193 will optimize the tail-call and allocate some more stack
194 space instead of way too much. */
195 return __mach_msg_server_timeout (demux, request->Head.msgh_size,
196 rcv_name, option, timeout);
197
198 case MACH_SEND_INVALID_DEST:
199 /* The reply can't be delivered, so destroy it. This error
6d52618b 200 indicates only that the requester went away, so we
28f540f4
RM
201 continue and get the next request. */
202 __mach_msg_destroy (&request->Head);
203 break;
204
205 default:
206 /* Some other form of lossage; return to caller. */
207 return mr;
208 }
209 }
210}
211weak_alias (__mach_msg_server_timeout, mach_msg_server_timeout)
212
213mach_msg_return_t
214__mach_msg_server (demux, max_size, rcv_name)
19c3f208 215 boolean_t (*demux) (mach_msg_header_t *in, mach_msg_header_t *out);
28f540f4
RM
216 mach_msg_size_t max_size;
217 mach_port_t rcv_name;
218{
219 return __mach_msg_server_timeout (demux, max_size, rcv_name,
220 MACH_MSG_OPTION_NONE,
221 MACH_MSG_TIMEOUT_NONE);
222}
223weak_alias (__mach_msg_server, mach_msg_server)