1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/* By-hand stubs for some RPC calls
Copyright (C) 1994 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <cthreads.h>
#include <stdlib.h>
#include <hurd/hurd_types.h>
#include <mach/message.h>
#include <string.h>
#include "proc.h"
/* From hurd/msg.defs: */
#define RPCID_SIG_POST 23000
struct msg_spec
{
int len;
void *contents;
};
/* Send the Mach message indicated by msg_spec; call cthread_exit
when it has been delivered. */
static void
blocking_message_send (struct msg_spec *message)
{
cthread_wire ();
mach_msg ((mach_msg_header_t *)message->contents, MACH_SEND_MSG,
message->len, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
cthread_exit (0);
}
/* Send signal SIGNO to MSGPORT with REFPORT as reference. Don't
block in any fashion. */
void
send_signal (mach_port_t msgport,
int signal,
mach_port_t refport)
{
error_t err;
static struct
{
mach_msg_header_t head;
mach_msg_type_t signaltype;
int signal;
mach_msg_type_t refporttype;
mach_port_t refport;
}
message =
{
{
/* Message header: */
(MACH_MSGH_BITS_COMPLEX
| MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND,
MACH_MSG_TYPE_MAKE_SEND_ONCE)), /* msgh_bits */
sizeof message, /* msgh_size */
0, /* msgh_remote_port */
MACH_PORT_NULL, /* msgh_local_port */
0, /* msgh_seqno */
RPCID_SIG_POST, /* msgh_id */
},
{
/* Type descriptor for signo */
MACH_MSG_TYPE_INTEGER_32, /* msgt_name */
32, /* msgt_size */
1, /* msgt_number */
1, /* msgt_inline */
0, /* msgt_longform */
0, /* msgt_deallocate */
0, /* msgt_unused */
},
/* Signal number */
0,
{
/* Type descriptor for refport */
MACH_MSG_TYPE_COPY_SEND, /* msgt_name */
32, /* msgt_size */
1, /* msgt_number */
1, /* msgt_unline */
0, /* msgt_longform */
0, /* msgt_deallocate */
0, /* msgt_unused */
},
/* Reference port */
MACH_PORT_NULL,
};
message.head.msgh_remote_port = msgport;
message.signal = signal;
message.refport = refport;
err = mach_msg((mach_msg_header_t *)&message,
MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof message, 0,
MACH_PORT_NULL, 0, MACH_PORT_NULL);
if (err == MACH_SEND_TIMEOUT)
{
struct msg_spec *msg_spec = malloc (sizeof (struct msg_spec));
msg_spec->len = sizeof message;
msg_spec->contents = malloc (sizeof message);
bcopy (&message, msg_spec->contents, sizeof message);
cthread_detach (cthread_fork ((cthread_fn_t) blocking_message_send,
msg_spec));
}
}
|