* locale/setlocale.c (_nl_C_name): Variable removed.
[glibc.git] / hurd / hurdmsg.c
blob32d1a5c9754dd62522007b60b229f8feae5ad5df
1 /* Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
19 #include <hurd.h>
20 #include <hurd/msg_server.h>
21 #include <hurd/fd.h>
22 #include <unistd.h>
23 #include <limits.h>
24 #include <string.h>
25 #include <argz.h>
28 #define AUTHCHECK \
29 if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \
30 return EPERM
33 /* Snarfing and frobbing the init ports. */
35 kern_return_t
36 _S_msg_get_init_port (mach_port_t msgport, mach_port_t auth, int which,
37 mach_port_t *result, mach_msg_type_name_t *result_type)
39 AUTHCHECK;
40 *result_type = MACH_MSG_TYPE_MOVE_SEND;
41 /* This function adds a new user reference for the *RESULT it gives back.
42 Our reply message uses a move-send right that consumes this reference. */
43 return _hurd_ports_get (which, result);
46 kern_return_t
47 _S_msg_set_init_port (mach_port_t msgport, mach_port_t auth,
48 int which, mach_port_t port)
50 error_t err;
52 AUTHCHECK;
54 err = _hurd_ports_set (which, port);
55 if (err == 0)
56 __mach_port_deallocate (__mach_task_self (), port);
58 return 0;
61 kern_return_t
62 _S_msg_get_init_ports (mach_port_t msgport, mach_port_t auth,
63 mach_port_t **ports,
64 mach_msg_type_name_t *ports_type,
65 mach_msg_type_number_t *nports)
67 mach_msg_type_number_t i;
68 error_t err;
70 AUTHCHECK;
72 if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) ports,
73 _hurd_nports * sizeof (mach_port_t), 1))
74 return err;
75 *nports = _hurd_nports;
77 for (i = 0; i < _hurd_nports; ++i)
78 /* This function adds a new user ref for the *RESULT it gives back.
79 Our reply message uses move-send rights that consumes this ref. */
80 if (err = _hurd_ports_get (i, &(*ports)[i]))
82 /* Died part way through. Deallocate the ports already fetched. */
83 while (i-- > 0)
84 __mach_port_deallocate (__mach_task_self (), (*ports)[i]);
85 __vm_deallocate (__mach_task_self (),
86 (vm_address_t) *ports,
87 *nports * sizeof (mach_port_t));
88 return err;
91 *ports_type = MACH_MSG_TYPE_MOVE_SEND;
92 return 0;
95 kern_return_t
96 _S_msg_set_init_ports (mach_port_t msgport, mach_port_t auth,
97 mach_port_t *ports, mach_msg_type_number_t nports)
99 mach_msg_type_number_t i;
100 error_t err;
102 AUTHCHECK;
104 for (i = 0; i < _hurd_nports; ++i)
106 if (err = _hurd_ports_set (i, ports[i]))
107 return err;
108 else
109 __mach_port_deallocate (__mach_task_self (), ports[i]);
112 return 0;
115 /* Snarfing and frobbing the init ints. */
117 static kern_return_t
118 get_int (int which, int *value)
120 switch (which)
122 case INIT_UMASK:
123 *value = _hurd_umask;
124 return 0;
125 case INIT_SIGMASK:
127 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
128 __spin_lock (&ss->lock);
129 *value = ss->blocked;
130 __spin_unlock (&ss->lock);
131 return 0;
133 case INIT_SIGPENDING:
135 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
136 __spin_lock (&ss->lock);
137 *value = ss->pending;
138 __spin_unlock (&ss->lock);
139 return 0;
141 case INIT_SIGIGN:
143 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
144 sigset_t ign;
145 int sig;
146 __spin_lock (&ss->lock);
147 __sigemptyset (&ign);
148 for (sig = 1; sig < NSIG; ++sig)
149 if (ss->actions[sig].sa_handler == SIG_IGN)
150 __sigaddset (&ign, sig);
151 __spin_unlock (&ss->lock);
152 *value = ign;
153 return 0;
155 default:
156 return EINVAL;
160 kern_return_t
161 _S_msg_get_init_int (mach_port_t msgport, mach_port_t auth,
162 int which, int *value)
164 AUTHCHECK;
166 return get_int (which, value);
169 kern_return_t
170 _S_msg_get_init_ints (mach_port_t msgport, mach_port_t auth,
171 int **values, mach_msg_type_number_t *nvalues)
173 error_t err;
174 mach_msg_type_number_t i;
176 AUTHCHECK;
178 if (err = __vm_allocate (__mach_task_self (), (vm_address_t *) values,
179 INIT_INT_MAX * sizeof (int), 1))
180 return err;
181 *nvalues = INIT_INT_MAX;
183 for (i = 0; i < INIT_INT_MAX; ++i)
184 switch (err = get_int (i, &(*values)[i]))
186 case 0: /* Success. */
187 break;
188 case EINVAL: /* Unknown index. */
189 (*values)[i] = 0;
190 break;
191 default: /* Lossage. */
192 __vm_deallocate (__mach_task_self (),
193 (vm_address_t) *values, INIT_INT_MAX * sizeof (int));
194 return err;
197 return 0;
201 static kern_return_t
202 set_int (int which, int value)
204 switch (which)
206 case INIT_UMASK:
207 _hurd_umask = value;
208 return 0;
210 /* These are pretty odd things to do. But you asked for it. */
211 case INIT_SIGMASK:
213 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
214 __spin_lock (&ss->lock);
215 ss->blocked = value;
216 __spin_unlock (&ss->lock);
217 return 0;
219 case INIT_SIGPENDING:
221 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
222 __spin_lock (&ss->lock);
223 ss->pending = value;
224 __spin_unlock (&ss->lock);
225 return 0;
227 case INIT_SIGIGN:
229 struct hurd_sigstate *ss = _hurd_thread_sigstate (_hurd_sigthread);
230 int sig;
231 const sigset_t ign = value;
232 __spin_lock (&ss->lock);
233 for (sig = 1; sig < NSIG; ++sig)
235 if (__sigismember (&ign, sig))
236 ss->actions[sig].sa_handler = SIG_IGN;
237 else if (ss->actions[sig].sa_handler == SIG_IGN)
238 ss->actions[sig].sa_handler = SIG_DFL;
240 __spin_unlock (&ss->lock);
241 return 0;
243 default:
244 return EINVAL;
248 kern_return_t
249 _S_msg_set_init_int (mach_port_t msgport, mach_port_t auth,
250 int which, int value)
252 AUTHCHECK;
254 return set_int (which, value);
257 kern_return_t
258 _S_msg_set_init_ints (mach_port_t msgport, mach_port_t auth,
259 int *values, mach_msg_type_number_t nvalues)
261 error_t err;
262 mach_msg_type_number_t i;
264 AUTHCHECK;
266 for (i = 0; i < INIT_INT_MAX; ++i)
267 switch (err = set_int (i, values[i]))
269 case 0: /* Success. */
270 break;
271 case EINVAL: /* Unknown index. */
272 break;
273 default: /* Lossage. */
274 return err;
277 return 0;
281 kern_return_t
282 _S_msg_get_fd (mach_port_t msgport, mach_port_t auth, int which,
283 mach_port_t *result, mach_msg_type_name_t *result_type)
285 AUTHCHECK;
287 /* This creates a new user reference for the send right.
288 Our reply message will move that reference to the caller. */
289 *result = __getdport (which);
290 if (*result == MACH_PORT_NULL)
291 return errno;
292 *result_type = MACH_MSG_TYPE_MOVE_SEND;
294 return 0;
297 kern_return_t
298 _S_msg_set_fd (mach_port_t msgport, mach_port_t auth,
299 int which, mach_port_t port)
301 AUTHCHECK;
303 /* We consume the reference if successful. */
304 return HURD_FD_USE (which, (_hurd_port2fd (descriptor, port, 0), 0));
307 /* Snarfing and frobbing environment variables. */
309 kern_return_t
310 _S_msg_get_env_variable (mach_port_t msgport,
311 char *variable,
312 char **data, mach_msg_type_number_t *datalen)
314 const char *value = getenv (variable);
316 if (value == NULL)
317 return ENOENT;
319 /* XXX this pointer might become invalid */
320 *data = value;
321 *datalen = strlen (value);
322 return 0;
326 kern_return_t
327 _S_msg_set_env_variable (mach_port_t msgport, mach_port_t auth,
328 char *variable,
329 char *value,
330 int replace)
332 AUTHCHECK;
334 if (setenv (variable, value, replace)) /* XXX name space */
335 return errno;
336 return 0;
339 kern_return_t
340 _S_msg_get_environment (mach_port_t msgport,
341 char **data, mach_msg_type_number_t *datalen)
343 /* Pack the environment into an array with nulls separating elements. */
344 if (__environ != NULL)
346 char *ap, **p;
347 size_t envlen = 0;
349 for (p = __environ; *p != NULL; ++p)
350 envlen += strlen (*p) + 1;
352 if (envlen > *datalen)
354 if (__vm_allocate (__mach_task_self (),
355 (vm_address_t *) data, envlen, 1))
356 return ENOMEM;
359 ap = *data;
360 for (p = __environ; *p != NULL; ++p)
361 ap = __memccpy (ap, *p, '\0', ULONG_MAX);
363 *datalen = envlen;
365 else
366 *datalen = 0;
368 return 0;
371 kern_return_t
372 _S_msg_set_environment (mach_port_t msgport, mach_port_t auth,
373 char *data, mach_msg_type_number_t datalen)
375 int _hurd_split_args (char *, mach_msg_type_number_t, char **);
376 int envc;
377 char **envp;
379 AUTHCHECK;
381 envc = __argz_count (data, datalen);
382 envp = malloc ((envc + 1) * sizeof (char *));
383 if (envp == NULL)
384 return errno;
385 __argz_extract (data, datalen, envp);
386 __environ = envp; /* XXX cooperate with loadenv et al */
387 return 0;
391 /* XXX */
393 kern_return_t
394 _S_msg_get_dtable (mach_port_t process,
395 mach_port_t refport,
396 portarray_t *dtable,
397 mach_msg_type_name_t *dtablePoly,
398 mach_msg_type_number_t *dtableCnt)
399 { return EOPNOTSUPP; }
401 kern_return_t
402 _S_msg_set_dtable (mach_port_t process,
403 mach_port_t refport,
404 portarray_t dtable,
405 mach_msg_type_number_t dtableCnt)
406 { return EOPNOTSUPP; }