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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
commit 2a54ebafd46a26d537ac38d46dc82568f751cc42
Author: Jeremie Koenig <jk@jk.fr.eu.org>
Date: Wed Jun 8 03:00:37 2011 +0000
proc: send signals with POSIX sigcodes
* proc/stubs.c (send_signal): Add a sigcode argument.
* proc/proc.h (send_signal): Declare the sigcode argument.
* proc/pgrp.c (leave_pgrp): Specify a null sigcode.
* proc/wait.c (alert_parent): Use CLD_EXITED for SIGCHLD on exit.
(S_proc_mark_stop): Use CLD_STOPPED for SIGCHLD on stop.
diff --git a/proc/pgrp.c b/proc/pgrp.c
index 2d6ca93..72c09ba 100644
--- a/proc/pgrp.c
+++ b/proc/pgrp.c
@@ -399,42 +399,42 @@ leave_pgrp (struct proc *p)
else if (p->p_parent->p_pgrp != pg
&& p->p_parent->p_pgrp->pg_session == pg->pg_session
&& !--pg->pg_orphcnt)
{
/* We were the last process keeping this from being
an orphaned process group -- do the orphaning gook */
struct proc *ip;
int dosignal = 0;
for (ip = pg->pg_plist; ip; ip = ip->p_gnext)
{
if (ip->p_stopped)
dosignal = 1;
if (ip->p_msgport != MACH_PORT_NULL)
nowait_msg_proc_newids (ip->p_msgport, ip->p_task, ip->p_parent->p_pid,
ip->p_pid, 1);
}
if (dosignal)
for (ip = pg->pg_plist; ip; ip = ip->p_gnext)
{
- send_signal (ip->p_msgport, SIGHUP, ip->p_task);
- send_signal (ip->p_msgport, SIGCONT, ip->p_task);
+ send_signal (ip->p_msgport, SIGHUP, 0, ip->p_task);
+ send_signal (ip->p_msgport, SIGCONT, 0, ip->p_task);
}
}
}
/* Cause process P to join its process group. */
void
join_pgrp (struct proc *p)
{
struct pgrp *pg = p->p_pgrp;
struct proc *tp;
int origorphcnt;
p->p_gnext = pg->pg_plist;
p->p_gprevp = &pg->pg_plist;
if (pg->pg_plist)
pg->pg_plist->p_gprevp = &p->p_gnext;
pg->pg_plist = p;
origorphcnt = !!pg->pg_orphcnt;
if (p->p_parent->p_pgrp != pg
diff --git a/proc/proc.h b/proc/proc.h
index 7943e0b..b52ca1d 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -192,19 +192,19 @@ void exc_clean (void *);
struct proc *allocate_proc (task_t);
void proc_death_notify (struct proc *);
void complete_proc (struct proc *, pid_t);
void leave_pgrp (struct proc *);
void join_pgrp (struct proc *);
void boot_setsid (struct proc *);
void process_has_exited (struct proc *);
void alert_parent (struct proc *);
void reparent_zombies (struct proc *);
void complete_exit (struct proc *);
void initialize_version_info (void);
-void send_signal (mach_port_t, int, mach_port_t);
+void send_signal (mach_port_t, int, int, mach_port_t);
#endif
diff --git a/proc/stubs.c b/proc/stubs.c
index de3a9b1..ee8e578 100644
--- a/proc/stubs.c
+++ b/proc/stubs.c
@@ -59,40 +59,41 @@ blocking_message_send (any_t arg)
case MACH_SEND_INTERRUPTED:
case MACH_SEND_INVALID_NOTIFY:
case MACH_SEND_NO_NOTIFY:
case MACH_SEND_NOTIFY_IN_PROGRESS:
assert_perror (err);
break;
default: /* Other errors are safe to ignore. */
break;
}
return 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,
+ int sigcode,
mach_port_t refport)
{
error_t err;
/* This message buffer might be modified by mach_msg in some error cases,
so we cannot safely use a shared static buffer. */
struct msg_sig_post_request 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 */
msgport, /* msgh_remote_port */
MACH_PORT_NULL, /* msgh_local_port */
0, /* msgh_seqno */
RPCID_SIG_POST, /* msgh_id */
},
{
@@ -101,41 +102,41 @@ send_signal (mach_port_t msgport,
32, /* msgt_size */
1, /* msgt_number */
1, /* msgt_inline */
0, /* msgt_longform */
0, /* msgt_deallocate */
0, /* msgt_unused */
},
/* Signal number */
signal,
/* Type descriptor for sigcode */
{
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 */
},
/* Sigcode */
- 0,
+ sigcode,
{
/* Type descriptor for refport */
MACH_MSG_TYPE_COPY_SEND, /* msgt_name */
32, /* msgt_size */
1, /* msgt_number */
1, /* msgt_inline */
0, /* msgt_longform */
0, /* msgt_deallocate */
0, /* msgt_unused */
},
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);
switch (err)
{
case MACH_SEND_TIMED_OUT:
/* The send could not complete immediately, and we do not want to
diff --git a/proc/wait.c b/proc/wait.c
index 6fc94e8..332aaf6 100644
--- a/proc/wait.c
+++ b/proc/wait.c
@@ -127,41 +127,41 @@ sample_rusage (struct proc *p)
/* Return nonzero if a `waitpid' on WAIT_PID by a process
in MYPGRP cares about the death of PID/PGRP. */
static inline int
waiter_cares (pid_t wait_pid, pid_t mypgrp,
pid_t pid, pid_t pgrp)
{
return (wait_pid == pid ||
wait_pid == -pgrp ||
wait_pid == WAIT_ANY ||
(wait_pid == WAIT_MYPGRP && pgrp == mypgrp));
}
/* A process is dying. Send SIGCHLD to the parent.
Wake the parent if it is waiting for us to exit. */
void
alert_parent (struct proc *p)
{
/* We accumulate the aggregate usage stats of all our dead children. */
rusage_add (&p->p_parent->p_child_rusage, &p->p_rusage);
- send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task);
+ send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_EXITED, p->p_parent->p_task);
if (!p->p_exiting)
{
p->p_status = W_EXITCODE (0, SIGKILL);
p->p_sigcode = -1;
}
if (p->p_parent->p_waiting)
{
pthread_cond_broadcast (&p->p_parent->p_wakeup);
p->p_parent->p_waiting = 0;
}
}
kern_return_t
S_proc_wait (struct proc *p,
mach_port_t reply_port,
mach_msg_type_name_t reply_port_type,
pid_t pid,
int options,
@@ -240,41 +240,41 @@ S_proc_wait (struct proc *p,
kern_return_t
S_proc_mark_stop (struct proc *p,
int signo,
int sigcode)
{
if (!p)
return EOPNOTSUPP;
p->p_stopped = 1;
p->p_status = W_STOPCODE (signo);
p->p_sigcode = sigcode;
p->p_waited = 0;
if (p->p_parent->p_waiting)
{
pthread_cond_broadcast (&p->p_parent->p_wakeup);
p->p_parent->p_waiting = 0;
}
if (!p->p_parent->p_nostopcld)
- send_signal (p->p_parent->p_msgport, SIGCHLD, p->p_parent->p_task);
+ send_signal (p->p_parent->p_msgport, SIGCHLD, CLD_STOPPED, p->p_parent->p_task);
return 0;
}
/* Implement proc_mark_exit as described in <hurd/process.defs>. */
kern_return_t
S_proc_mark_exit (struct proc *p,
int status,
int sigcode)
{
if (!p)
return EOPNOTSUPP;
if (WIFSTOPPED (status))
return EINVAL;
sample_rusage (p); /* See comments above sample_rusage. */
if (p->p_exiting)
return EBUSY;
|