]> git.ipfire.org Git - thirdparty/glibc.git/blame - mach/msgserver.c
iconv, localedef: avoid floating point rounding differences [BZ #24372]
[thirdparty/glibc.git] / mach / msgserver.c
CommitLineData
04277e02 1/* Copyright (C) 1993-2019 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 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
28f540f4
RM
17
18/* Based on CMU's mach_msg_server.c revision 2.4 of 91/05/14, and thus
19 under the following copyright. Rewritten by Roland McGrath (FSF)
20 93/12/06 to use stack space instead of malloc, and to handle
21 large messages with MACH_RCV_LARGE. */
22
19c3f208 23/*
28f540f4
RM
24 * Mach Operating System
25 * Copyright (c) 1991,1990 Carnegie Mellon University
26 * All Rights Reserved.
19c3f208 27 *
28f540f4
RM
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
19c3f208 33 *
28f540f4
RM
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19c3f208 37 *
28f540f4 38 * Carnegie Mellon requests users of this software to return to
19c3f208 39 *
28f540f4
RM
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
19c3f208 44 *
28f540f4
RM
45 * any improvements or extensions that they make and grant Carnegie Mellon
46 * the rights to redistribute these changes.
47 */
48/*
eff75b8d 49 * (pre-GNU) HISTORY
28f540f4
RM
50 *
51 * Revision 2.4 91/05/14 17:53:22 mrt
52 * Correcting copyright
19c3f208 53 *
28f540f4
RM
54 * Revision 2.3 91/02/14 14:17:47 mrt
55 * Added new Mach copyright
56 * [91/02/13 12:44:20 mrt]
19c3f208 57 *
28f540f4
RM
58 * Revision 2.2 90/08/06 17:23:58 rpd
59 * Created.
19c3f208 60 *
28f540f4
RM
61 */
62
63
64#include <mach.h>
65#include <mach/mig_errors.h>
66#include <stdlib.h> /* For malloc and free. */
6c2a1e81 67#include <assert.h>
28f540f4 68
61c83c3f
RM
69#ifdef NDR_CHAR_ASCII /* OSF Mach flavors have different names. */
70# define mig_reply_header_t mig_reply_error_t
71#endif
72
28f540f4
RM
73mach_msg_return_t
74__mach_msg_server_timeout (boolean_t (*demux) (mach_msg_header_t *request,
75 mach_msg_header_t *reply),
76 mach_msg_size_t max_size,
77 mach_port_t rcv_name,
78 mach_msg_option_t option,
79 mach_msg_timeout_t timeout)
80{
2e09a79a
JM
81 mig_reply_header_t *request, *reply;
82 mach_msg_return_t mr;
28f540f4
RM
83
84 if (max_size == 0)
85 {
21297437 86#ifdef MACH_RCV_LARGE
28f540f4
RM
87 option |= MACH_RCV_LARGE;
88 max_size = 2 * __vm_page_size; /* Generic. Good? XXX */
21297437
RM
89#else
90 max_size = 4 * __vm_page_size; /* XXX */
91#endif
28f540f4
RM
92 }
93
94 request = __alloca (max_size);
95 reply = __alloca (max_size);
96
97 while (1)
98 {
99 get_request:
100 mr = __mach_msg (&request->Head, MACH_RCV_MSG|option,
101 0, max_size, rcv_name,
102 timeout, MACH_PORT_NULL);
103 while (mr == MACH_MSG_SUCCESS)
104 {
105 /* We have a request message.
106 Pass it to DEMUX for processing. */
107
108 (void) (*demux) (&request->Head, &reply->Head);
6c2a1e81 109 assert (reply->Head.msgh_size <= max_size);
28f540f4
RM
110
111 switch (reply->RetCode)
112 {
113 case KERN_SUCCESS:
114 /* Hunky dory. */
115 break;
116
117 case MIG_NO_REPLY:
118 /* The server function wanted no reply sent.
119 Loop for another request. */
120 goto get_request;
121
122 default:
123 /* Some error; destroy the request message to release any
124 port rights or VM it holds. Don't destroy the reply port
125 right, so we can send an error message. */
126 request->Head.msgh_remote_port = MACH_PORT_NULL;
127 __mach_msg_destroy (&request->Head);
128 break;
129 }
130
131 if (reply->Head.msgh_remote_port == MACH_PORT_NULL)
132 {
133 /* No reply port, so destroy the reply. */
134 if (reply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)
135 __mach_msg_destroy (&reply->Head);
136 goto get_request;
137 }
138
139 /* Send the reply and the get next request. */
140
141 {
142 /* Swap the request and reply buffers. mach_msg will read the
143 reply message from the buffer we pass and write the new
144 request message to the same buffer. */
145 void *tmp = request;
146 request = reply;
147 reply = tmp;
148 }
149
150 mr = __mach_msg (&request->Head,
151 MACH_SEND_MSG|MACH_RCV_MSG|option,
152 request->Head.msgh_size, max_size, rcv_name,
153 timeout, MACH_PORT_NULL);
154 }
155
156 /* A message error occurred. */
157
158 switch (mr)
159 {
160 case MACH_RCV_TOO_LARGE:
21297437 161#ifdef MACH_RCV_LARGE
28f540f4 162 /* The request message is larger than MAX_SIZE, and has not
6d52618b 163 been dequeued. The message header has the actual size of
28f540f4
RM
164 the message. We recurse here in hopes that the compiler
165 will optimize the tail-call and allocate some more stack
166 space instead of way too much. */
167 return __mach_msg_server_timeout (demux, request->Head.msgh_size,
168 rcv_name, option, timeout);
21297437
RM
169#else
170 /* XXX the kernel has destroyed the msg */
171 break;
172#endif
28f540f4
RM
173
174 case MACH_SEND_INVALID_DEST:
175 /* The reply can't be delivered, so destroy it. This error
6d52618b 176 indicates only that the requester went away, so we
28f540f4
RM
177 continue and get the next request. */
178 __mach_msg_destroy (&request->Head);
179 break;
180
181 default:
182 /* Some other form of lossage; return to caller. */
183 return mr;
184 }
185 }
186}
187weak_alias (__mach_msg_server_timeout, mach_msg_server_timeout)
188
189mach_msg_return_t
80d9be81
JM
190__mach_msg_server (boolean_t (*demux) (mach_msg_header_t *in,
191 mach_msg_header_t *out),
192 mach_msg_size_t max_size,
193 mach_port_t rcv_name)
28f540f4
RM
194{
195 return __mach_msg_server_timeout (demux, max_size, rcv_name,
196 MACH_MSG_OPTION_NONE,
197 MACH_MSG_TIMEOUT_NONE);
198}
199weak_alias (__mach_msg_server, mach_msg_server)