1 /* Copyright (C) 1992-2023 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 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.
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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
19 #include <hurd/msg_server.h>
28 if (auth != mach_task_self () && ! __USEPORT (AUTH, port == auth)) \
32 /* Snarfing and frobbing the init ports. */
35 _S_msg_get_init_port (mach_port_t msgport
, mach_port_t auth
, int which
,
36 mach_port_t
*result
, mach_msg_type_name_t
*result_type
)
42 *result_type
= MACH_MSG_TYPE_MOVE_SEND
;
43 /* This function adds a new user reference for the *RESULT it gives back.
44 Our reply message uses a move-send right that consumes this reference. */
45 err
= _hurd_ports_get (which
, result
);
46 if (!err
&& MACH_PORT_VALID (auth
))
47 __mach_port_deallocate (__mach_task_self (), auth
);
52 _S_msg_set_init_port (mach_port_t msgport
, mach_port_t auth
,
53 int which
, mach_port_t port
)
59 err
= _hurd_ports_set (which
, port
);
61 if (!err
&& MACH_PORT_VALID (port
))
62 __mach_port_deallocate (__mach_task_self (), port
);
63 if (!err
&& MACH_PORT_VALID (auth
))
64 __mach_port_deallocate (__mach_task_self (), auth
);
70 _S_msg_get_init_ports (mach_port_t msgport
, mach_port_t auth
,
72 mach_msg_type_name_t
*ports_type
,
73 mach_msg_type_number_t
*nports
)
75 mach_msg_type_number_t i
;
80 if (err
= __vm_allocate (__mach_task_self (), (vm_address_t
*) ports
,
81 _hurd_nports
* sizeof (mach_port_t
), 1))
83 *nports
= _hurd_nports
;
85 for (i
= 0; i
< _hurd_nports
; ++i
)
86 /* This function adds a new user ref for the *RESULT it gives back.
87 Our reply message uses move-send rights that consumes this ref. */
88 if (err
= _hurd_ports_get (i
, &(*ports
)[i
]))
90 /* Died part way through. Deallocate the ports already fetched. */
92 __mach_port_deallocate (__mach_task_self (), (*ports
)[i
]);
93 __vm_deallocate (__mach_task_self (),
94 (vm_address_t
) *ports
,
95 *nports
* sizeof (mach_port_t
));
99 *ports_type
= MACH_MSG_TYPE_MOVE_SEND
;
100 if (MACH_PORT_VALID (auth
))
101 __mach_port_deallocate (__mach_task_self (), auth
);
106 _S_msg_set_init_ports (mach_port_t msgport
, mach_port_t auth
,
107 const mach_port_t
*ports
, mach_msg_type_number_t nports
)
109 mach_msg_type_number_t i
;
114 for (i
= 0; i
< _hurd_nports
; ++i
)
116 if (err
= _hurd_ports_set (i
, ports
[i
]))
119 __mach_port_deallocate (__mach_task_self (), ports
[i
]);
122 if (MACH_PORT_VALID (auth
))
123 __mach_port_deallocate (__mach_task_self (), auth
);
127 /* Snarfing and frobbing the init ints. */
130 get_int (int which
, int *value
)
135 *value
= _hurd_umask
;
137 case INIT_SIGPENDING
:
139 struct hurd_sigstate
*ss
= _hurd_global_sigstate
;
140 __spin_lock (&ss
->lock
);
141 *value
= ss
->pending
;
142 __spin_unlock (&ss
->lock
);
147 struct hurd_sigstate
*ss
= _hurd_global_sigstate
;
150 __spin_lock (&ss
->lock
);
151 __sigemptyset (&ign
);
152 for (sig
= 1; sig
< NSIG
; ++sig
)
153 if (ss
->actions
[sig
].sa_handler
== SIG_IGN
)
154 __sigaddset (&ign
, sig
);
155 __spin_unlock (&ss
->lock
);
165 _S_msg_get_init_int (mach_port_t msgport
, mach_port_t auth
,
166 int which
, int *value
)
172 err
= get_int (which
, value
);
175 if (MACH_PORT_VALID (auth
))
176 __mach_port_deallocate (__mach_task_self (), auth
);
181 _S_msg_get_init_ints (mach_port_t msgport
, mach_port_t auth
,
182 int **values
, mach_msg_type_number_t
*nvalues
)
185 mach_msg_type_number_t i
;
189 if (err
= __vm_allocate (__mach_task_self (), (vm_address_t
*) values
,
190 INIT_INT_MAX
* sizeof (int), 1))
192 *nvalues
= INIT_INT_MAX
;
194 for (i
= 0; i
< INIT_INT_MAX
; ++i
)
195 switch (err
= get_int (i
, &(*values
)[i
]))
197 case 0: /* Success. */
199 case EINVAL
: /* Unknown index. */
202 default: /* Lossage. */
203 __vm_deallocate (__mach_task_self (),
204 (vm_address_t
) *values
, INIT_INT_MAX
* sizeof (int));
208 if (MACH_PORT_VALID (auth
))
209 __mach_port_deallocate (__mach_task_self (), auth
);
215 set_int (int which
, int value
)
223 /* These are pretty odd things to do. But you asked for it. */
224 case INIT_SIGPENDING
:
226 struct hurd_sigstate
*ss
= _hurd_global_sigstate
;
227 __spin_lock (&ss
->lock
);
229 __spin_unlock (&ss
->lock
);
234 struct hurd_sigstate
*ss
= _hurd_global_sigstate
;
236 const sigset_t ign
= value
;
237 __spin_lock (&ss
->lock
);
238 for (sig
= 1; sig
< NSIG
; ++sig
)
240 if (__sigismember (&ign
, sig
))
241 ss
->actions
[sig
].sa_handler
= SIG_IGN
;
242 else if (ss
->actions
[sig
].sa_handler
== SIG_IGN
)
243 ss
->actions
[sig
].sa_handler
= SIG_DFL
;
245 __spin_unlock (&ss
->lock
);
249 _hurdsig_traced
= value
;
258 _S_msg_set_init_int (mach_port_t msgport
, mach_port_t auth
,
259 int which
, int value
)
265 err
= set_int (which
, value
);
268 if (MACH_PORT_VALID (auth
))
269 __mach_port_deallocate (__mach_task_self (), auth
);
274 _S_msg_set_init_ints (mach_port_t msgport
, mach_port_t auth
,
275 const int *values
, mach_msg_type_number_t nvalues
)
278 mach_msg_type_number_t i
;
282 for (i
= 0; i
< INIT_INT_MAX
; ++i
)
283 switch (err
= set_int (i
, values
[i
]))
285 case 0: /* Success. */
287 case EINVAL
: /* Unknown index. */
289 default: /* Lossage. */
293 if (MACH_PORT_VALID (auth
))
294 __mach_port_deallocate (__mach_task_self (), auth
);
300 _S_msg_get_fd (mach_port_t msgport
, mach_port_t auth
, int which
,
301 mach_port_t
*result
, mach_msg_type_name_t
*result_type
)
305 /* This creates a new user reference for the send right.
306 Our reply message will move that reference to the caller. */
307 *result
= __getdport (which
);
308 if (*result
== MACH_PORT_NULL
)
310 *result_type
= MACH_MSG_TYPE_MOVE_SEND
;
312 if (MACH_PORT_VALID (auth
))
313 __mach_port_deallocate (__mach_task_self (), auth
);
318 _S_msg_set_fd (mach_port_t msgport
, mach_port_t auth
,
319 int which
, mach_port_t port
)
325 /* We consume the reference if successful. */
326 err
= HURD_FD_USE (which
,
328 int flags
= (descriptor
->flags
& FD_CLOEXEC
)
330 _hurd_port2fd (descriptor
, port
, flags
);
336 if (MACH_PORT_VALID (auth
))
337 __mach_port_deallocate (__mach_task_self (), auth
);
341 /* Snarfing and frobbing environment variables. */
344 _S_msg_get_env_variable (mach_port_t msgport
,
345 const_string_t variable
,
346 char **data
, mach_msg_type_number_t
*datalen
)
349 mach_msg_type_number_t valuelen
;
350 const char *value
= getenv (variable
);
355 valuelen
= strlen (value
);
356 if (valuelen
> *datalen
)
358 if (err
= __vm_allocate (__mach_task_self (),
359 (vm_address_t
*) data
, valuelen
, 1))
363 memcpy (*data
, value
, valuelen
);
371 _S_msg_set_env_variable (mach_port_t msgport
, mach_port_t auth
,
372 const_string_t variable
,
373 const_string_t value
,
378 if (__setenv (variable
, value
, replace
)) /* XXX name space */
381 if (MACH_PORT_VALID (auth
))
382 __mach_port_deallocate (__mach_task_self (), auth
);
387 _S_msg_get_environment (mach_port_t msgport
,
388 char **data
, mach_msg_type_number_t
*datalen
)
390 /* Pack the environment into an array with nulls separating elements. */
391 if (__environ
!= NULL
)
396 for (p
= __environ
; *p
!= NULL
; ++p
)
397 envlen
+= strlen (*p
) + 1;
399 if (envlen
> *datalen
)
401 if (__vm_allocate (__mach_task_self (),
402 (vm_address_t
*) data
, envlen
, 1))
407 for (p
= __environ
; *p
!= NULL
; ++p
)
408 ap
= __memccpy (ap
, *p
, '\0', ULONG_MAX
);
419 _S_msg_set_environment (mach_port_t msgport
, mach_port_t auth
,
420 const char *data
, mach_msg_type_number_t datalen
)
422 int _hurd_split_args (char *, mach_msg_type_number_t
, char **);
428 envc
= __argz_count (data
, datalen
);
429 envp
= malloc ((envc
+ 1) * sizeof (char *));
432 __argz_extract (data
, datalen
, envp
);
433 __environ
= envp
; /* XXX cooperate with loadenv et al */
435 if (MACH_PORT_VALID (auth
))
436 __mach_port_deallocate (__mach_task_self (), auth
);
442 _S_msg_get_dtable (mach_port_t process
,
445 mach_msg_type_name_t
*dtablePoly
,
446 mach_msg_type_number_t
*dtableCnt
)
449 mach_msg_type_number_t i
;
455 __mutex_lock (&_hurd_dtable_lock
);
457 if (err
= __vm_allocate (__mach_task_self (), (vm_address_t
*) &ports
,
458 _hurd_dtablesize
* sizeof(mach_port_t
), 1))
461 for (i
= 0; i
< _hurd_dtablesize
; i
++)
463 struct hurd_fd
*cell
= _hurd_dtable
[i
];
465 ports
[i
] = MACH_PORT_NULL
;
468 __spin_lock (&cell
->port
.lock
);
469 if (cell
->port
.port
== MACH_PORT_NULL
)
470 ports
[i
] = MACH_PORT_NULL
;
473 ports
[i
] = cell
->port
.port
;
474 /* We will move this send right. */
475 __mach_port_mod_refs (__mach_task_self (), ports
[i
],
476 MACH_PORT_RIGHT_SEND
, +1);
478 __spin_unlock (&cell
->port
.lock
);
483 *dtablePoly
= MACH_MSG_TYPE_MOVE_SEND
;
484 *dtableCnt
= _hurd_dtablesize
;
487 __mutex_unlock (&_hurd_dtable_lock
);
489 if (!err
&& MACH_PORT_VALID (auth
))
490 __mach_port_deallocate (__mach_task_self (), auth
);
497 _S_msg_set_dtable (mach_port_t process
,
499 const_portarray_t dtable
,
500 mach_msg_type_number_t dtableCnt
)
501 { return EOPNOTSUPP
; }