1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <hurd.h>
21: #include <hurd/signal.h>
22: #include <hurd/fd.h>
23: #include <string.h>
24: #include <assert.h>
25: #include <hurd/msg_server.h>
26: #include <thread_state.h>
27: #include <intr-msg.h>
28:
29: static char *
30: describe_number (string_t description, const char *flavor, long int i)
31: {
32: unsigned long int j;
33: char *p = flavor ? description : __stpcpy (description, flavor);
34: char *end;
35:
36:
37: if (i < 0)
38: {
39: i = -i;
40: *p++ = '-';
41: }
42:
43:
44: for (j = i; j >= 10; j /= 10)
45: p++;
46: end = p + 1;
47: *end = '\0';
48:
49: do
50: {
51: *p-- = '0' + i % 10;
52: i /= 10;
53: } while (i != 0);
54:
55: return end;
56: }
57:
58: static char *
59: describe_port (string_t description, mach_port_t port)
60: {
61: int i;
62:
63: if (port == MACH_PORT_NULL)
64: return __stpcpy (description, "(null)");
65: if (port == MACH_PORT_DEAD)
66: return __stpcpy (description, "(dead)");
67:
68: if (port == __mach_task_self ())
69: return __stpcpy (description, "task-self");
70:
71: for (i = 0; i < _hurd_nports; ++i)
72: if (port == _hurd_ports[i].port)
73: return describe_number (description, "init#", i);
74:
75: if (_hurd_init_dtable)
76: {
77: for (i = 0; i < _hurd_init_dtablesize; ++i)
78: if (port == _hurd_init_dtable[i])
79: return describe_number (description, "fd#", i);
80: }
81: else if (_hurd_dtable)
82: {
83: for (i = 0; i < _hurd_dtablesize; ++i)
84: if (_hurd_dtable[i] == NULL)
85: continue;
86: else if (port == _hurd_dtable[i]->port.port)
87: return describe_number (description, "fd#", i);
88: else if (port == _hurd_dtable[i]->ctty.port)
89: return describe_number (description, "bgfd#", i);
90: }
91:
92: return describe_number (description, "port#", port);
93: }
94:
95:
96:
97:
98: #if 0
99: extern thread_t _hurd_itimer_thread;
100: weak_extern (_hurd_itimer_thread)
101: #else
102: static thread_t default_hurd_itimer_thread;
103: weak_alias (default_hurd_itimer_thread, _hurd_itimer_thread)
104: #endif
105:
106: kern_return_t
107: _S_msg_report_wait (mach_port_t msgport, thread_t thread,
108: string_t description, mach_msg_id_t *msgid)
109: {
110: *msgid = 0;
111:
112: if (thread == _hurd_msgport_thread)
113:
114: strcpy (description, "msgport");
115: else if (&_hurd_itimer_thread && thread == _hurd_itimer_thread)
116: strcpy (description, "itimer");
117: else
118: {
119:
120:
121: struct hurd_sigstate *ss;
122:
123: __mutex_lock (&_hurd_siglock);
124: for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
125: if (ss->thread == thread)
126: break;
127: __mutex_unlock (&_hurd_siglock);
128: if (ss == NULL)
129:
130: return EINVAL;
131:
132: if (ss->suspended != MACH_PORT_NULL)
133: strcpy (description, "sigsuspend");
134: else
135: {
136:
137:
138: struct machine_thread_state state;
139: mach_msg_type_number_t count = MACHINE_THREAD_STATE_COUNT;
140: error_t err;
141:
142: err = __thread_get_state (thread, MACHINE_THREAD_STATE_FLAVOR,
143: (natural_t *) &state, &count);
144: if (err)
145: return err;
146: assert (count == MACHINE_THREAD_STATE_COUNT);
147: if (SYSCALL_EXAMINE (&state, msgid))
148: {
149: mach_port_t send_port, rcv_port;
150: mach_msg_option_t option;
151: mach_msg_timeout_t timeout;
152:
153:
154: if (*msgid == -25
155:
156: && MSG_EXAMINE (&state, msgid, &send_port, &rcv_port,
157: &option, &timeout) == 0)
158: {
159: char *p;
160: if (send_port != MACH_PORT_NULL && *msgid != 0)
161: {
162:
163:
164:
165:
166:
167: if (send_port == ss->intr_port)
168: {
169:
170:
171:
172: description[0] = '[';
173: p = describe_port (description + 1, send_port);
174: *p++ = ']';
175: *p = '\0';
176: }
177: else
178: (void) describe_port (description, send_port);
179: }
180: else if (rcv_port != MACH_PORT_NULL)
181: {
182:
183:
184:
185:
186:
187: strcpy (describe_port (description, rcv_port), ":rcv");
188: *msgid = 0;
189: }
190: else if ((option & (MACH_RCV_MSG|MACH_RCV_TIMEOUT))
191: == (MACH_RCV_MSG|MACH_RCV_TIMEOUT))
192: {
193:
194:
195:
196:
197: strcpy (describe_number (description, 0, timeout), "ms");
198: *msgid = 0;
199: }
200: else
201: {
202: strcpy (description, "mach_msg");
203: *msgid = 0;
204: }
205: }
206: else
207: {
208: (void) describe_number (description, "syscall#", *msgid);
209: *msgid = 0;
210: }
211: }
212: else
213: description[0] = '\0';
214: }
215: }
216:
217: __mach_port_deallocate (__mach_task_self (), thread);
218: return 0;
219: }
220:
221: kern_return_t
222: _S_msg_describe_ports (mach_port_t msgport, mach_port_t refport,
223: mach_port_t *ports, mach_msg_type_number_t nports,
224: char **desc, mach_msg_type_number_t *desclen)
225: {
226: char *p, *end;
227:
228: if (__USEPORT (AUTH, msgport != port))
229: return EPERM;
230:
231: end = *desc + *desclen;
232: p = *desc;
233: while (nports-- > 0)
234: {
235: char this[200];
236: describe_port (this, *ports++);
237: p = __stpncpy (p, this, end - p);
238: if (p == end && p[-1] != '\0')
239: return ENOMEM;
240: }
241:
242: *desclen = p - *desc;
243: return 0;
244: }