Rev 1072 | Rev 1086 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1072 | Rev 1084 | ||
|---|---|---|---|
| Line 45... | Line 45... | ||
| 45 | /* TODO: multi-threaded connect-to-me can cause race condition |
45 | /* TODO: multi-threaded connect-to-me can cause race condition |
| 46 | * on phone, add counter + thread_kill?? |
46 | * on phone, add counter + thread_kill?? |
| 47 | * |
47 | * |
| 48 | */ |
48 | */ |
| 49 | 49 | ||
| - | 50 | #define GET_CHECK_PHONE(phone,phoneid,err) { \ |
|
| - | 51 | if (phoneid > IPC_MAX_PHONES) { err; } \ |
|
| - | 52 | phone = &TASK->phones[phoneid]; \ |
|
| - | 53 | } |
|
| - | 54 | ||
| - | 55 | ||
| 50 | /** Return true if the method is a system method */ |
56 | /** Return true if the method is a system method */ |
| 51 | static inline int is_system_method(__native method) |
57 | static inline int is_system_method(__native method) |
| 52 | { |
58 | { |
| 53 | if (method <= IPC_M_LAST_SYSTEM) |
59 | if (method <= IPC_M_LAST_SYSTEM) |
| 54 | return 1; |
60 | return 1; |
| Line 148... | Line 154... | ||
| 148 | phone_t *phone; |
154 | phone_t *phone; |
| 149 | 155 | ||
| 150 | if (is_system_method(method)) |
156 | if (is_system_method(method)) |
| 151 | return EPERM; |
157 | return EPERM; |
| 152 | 158 | ||
| 153 | phone = get_phone_and_lock(phoneid); |
159 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 154 | if (!phone) |
- | |
| 155 | return ENOENT; |
- | |
| 156 | 160 | ||
| 157 | ipc_call_init(&call); |
161 | ipc_call_static_init(&call); |
| 158 | IPC_SET_METHOD(call.data, method); |
162 | IPC_SET_METHOD(call.data, method); |
| 159 | IPC_SET_ARG1(call.data, arg1); |
163 | IPC_SET_ARG1(call.data, arg1); |
| 160 | 164 | ||
| 161 | ipc_call_sync(phone, &call); |
165 | ipc_call_sync(phone, &call); |
| 162 | 166 | ||
| Line 170... | Line 174... | ||
| 170 | __native *reply) |
174 | __native *reply) |
| 171 | { |
175 | { |
| 172 | call_t call; |
176 | call_t call; |
| 173 | phone_t *phone; |
177 | phone_t *phone; |
| 174 | 178 | ||
| 175 | ipc_call_init(&call); |
179 | ipc_call_static_init(&call); |
| 176 | copy_from_uspace(&call.data, question, sizeof(call.data)); |
180 | copy_from_uspace(&call.data, question, sizeof(call.data)); |
| 177 | 181 | ||
| 178 | if (is_system_method(IPC_GET_METHOD(call.data))) |
182 | if (is_system_method(IPC_GET_METHOD(call.data))) |
| 179 | return EPERM; |
183 | return EPERM; |
| 180 | 184 | ||
| 181 | phone = get_phone_and_lock(phoneid); |
185 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 182 | if (!phone) |
- | |
| 183 | return ENOENT; |
- | |
| 184 | 186 | ||
| 185 | ipc_call_sync(phone, &call); |
187 | ipc_call_sync(phone, &call); |
| 186 | 188 | ||
| 187 | copy_to_uspace(reply, &call.data, sizeof(call.data)); |
189 | copy_to_uspace(reply, &call.data, sizeof(call.data)); |
| 188 | 190 | ||
| Line 217... | Line 219... | ||
| 217 | return IPC_CALLRET_FATAL; |
219 | return IPC_CALLRET_FATAL; |
| 218 | 220 | ||
| 219 | if (check_call_limit()) |
221 | if (check_call_limit()) |
| 220 | return IPC_CALLRET_TEMPORARY; |
222 | return IPC_CALLRET_TEMPORARY; |
| 221 | 223 | ||
| 222 | phone = get_phone_and_lock(phoneid); |
224 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 223 | if (!phone) |
- | |
| 224 | return IPC_CALLRET_FATAL; |
- | |
| 225 | 225 | ||
| 226 | call = ipc_call_alloc(); |
226 | call = ipc_call_alloc(); |
| 227 | IPC_SET_METHOD(call->data, method); |
227 | IPC_SET_METHOD(call->data, method); |
| 228 | IPC_SET_ARG1(call->data, arg1); |
228 | IPC_SET_ARG1(call->data, arg1); |
| 229 | IPC_SET_ARG2(call->data, arg2); |
229 | IPC_SET_ARG2(call->data, arg2); |
| Line 243... | Line 243... | ||
| 243 | phone_t *phone; |
243 | phone_t *phone; |
| 244 | 244 | ||
| 245 | if (check_call_limit()) |
245 | if (check_call_limit()) |
| 246 | return IPC_CALLRET_TEMPORARY; |
246 | return IPC_CALLRET_TEMPORARY; |
| 247 | 247 | ||
| 248 | phone = get_phone_and_lock(phoneid); |
248 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 249 | if (!phone) |
- | |
| 250 | return IPC_CALLRET_FATAL; |
- | |
| 251 | 249 | ||
| 252 | call = ipc_call_alloc(); |
250 | call = ipc_call_alloc(); |
| 253 | copy_from_uspace(&call->data, data, sizeof(call->data)); |
251 | copy_from_uspace(&call->data, data, sizeof(call->data)); |
| 254 | 252 | ||
| 255 | if (is_system_method(IPC_GET_METHOD(call->data))) { |
253 | if (is_system_method(IPC_GET_METHOD(call->data))) { |
| Line 277... | Line 275... | ||
| 277 | 275 | ||
| 278 | call = get_call(callid); |
276 | call = get_call(callid); |
| 279 | if (!call) |
277 | if (!call) |
| 280 | return ENOENT; |
278 | return ENOENT; |
| 281 | 279 | ||
| 282 | phone = get_phone_and_lock(phoneid); |
280 | GET_CHECK_PHONE(phone, phoneid, { |
| 283 | if (!phone) { |
- | |
| 284 | IPC_SET_RETVAL(call->data, EFORWARD); |
281 | IPC_SET_RETVAL(call->data, EFORWARD); |
| 285 | ipc_answer(&TASK->answerbox, call); |
282 | ipc_answer(&TASK->answerbox, call); |
| 286 | return ENOENT; |
283 | return ENOENT; |
| 287 | } |
284 | }); |
| 288 | 285 | ||
| 289 | if (!is_forwardable(IPC_GET_METHOD(call->data))) { |
286 | if (!is_forwardable(IPC_GET_METHOD(call->data))) { |
| 290 | IPC_SET_RETVAL(call->data, EFORWARD); |
287 | IPC_SET_RETVAL(call->data, EFORWARD); |
| 291 | ipc_answer(&TASK->answerbox, call); |
288 | ipc_answer(&TASK->answerbox, call); |
| 292 | return EPERM; |
289 | return EPERM; |
| Line 301... | Line 298... | ||
| 301 | } else { |
298 | } else { |
| 302 | IPC_SET_METHOD(call->data, method); |
299 | IPC_SET_METHOD(call->data, method); |
| 303 | IPC_SET_ARG1(call->data, arg1); |
300 | IPC_SET_ARG1(call->data, arg1); |
| 304 | } |
301 | } |
| 305 | 302 | ||
| 306 | ipc_forward(call, phone->callee, &TASK->answerbox); |
303 | ipc_forward(call, phone, &TASK->answerbox); |
| 307 | 304 | ||
| 308 | return 0; |
305 | return 0; |
| 309 | } |
306 | } |
| 310 | 307 | ||
| 311 | /** Send IPC answer */ |
308 | /** Send IPC answer */ |
| Line 369... | Line 366... | ||
| 369 | __native arg2, task_id_t *taskid) |
366 | __native arg2, task_id_t *taskid) |
| 370 | { |
367 | { |
| 371 | call_t call; |
368 | call_t call; |
| 372 | phone_t *phone; |
369 | phone_t *phone; |
| 373 | 370 | ||
| 374 | ipc_call_init(&call); |
371 | ipc_call_static_init(&call); |
| 375 | IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME); |
372 | IPC_SET_METHOD(call.data, IPC_M_CONNECTTOME); |
| 376 | IPC_SET_ARG1(call.data, arg1); |
373 | IPC_SET_ARG1(call.data, arg1); |
| 377 | IPC_SET_ARG2(call.data, arg2); |
374 | IPC_SET_ARG2(call.data, arg2); |
| 378 | 375 | ||
| 379 | phone = get_phone_and_lock(phoneid); |
376 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 380 | if (!phone) |
- | |
| 381 | return ENOENT; |
- | |
| 382 | 377 | ||
| 383 | ipc_call_sync(phone, &call); |
378 | ipc_call_sync(phone, &call); |
| 384 | 379 | ||
| 385 | if (!IPC_GET_RETVAL(call.data) && taskid) |
380 | if (!IPC_GET_RETVAL(call.data) && taskid) |
| 386 | copy_to_uspace(taskid, |
381 | copy_to_uspace(taskid, |
| Line 399... | Line 394... | ||
| 399 | { |
394 | { |
| 400 | call_t call; |
395 | call_t call; |
| 401 | phone_t *phone; |
396 | phone_t *phone; |
| 402 | int newphid; |
397 | int newphid; |
| 403 | 398 | ||
| 404 | phone = get_phone_and_lock(phoneid); |
399 | GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
| 405 | if (!phone) |
- | |
| 406 | return ENOENT; |
- | |
| 407 | 400 | ||
| 408 | newphid = phone_alloc(); |
401 | newphid = phone_alloc(); |
| 409 | if (newphid < 0) |
402 | if (newphid < 0) |
| 410 | return ELIMIT; |
403 | return ELIMIT; |
| 411 | 404 | ||
| 412 | ipc_call_init(&call); |
405 | ipc_call_static_init(&call); |
| 413 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
406 | IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); |
| 414 | IPC_SET_ARG1(call.data, arg1); |
407 | IPC_SET_ARG1(call.data, arg1); |
| 415 | IPC_SET_ARG2(call.data, arg2); |
408 | IPC_SET_ARG2(call.data, arg2); |
| 416 | IPC_SET_ARG3(call.data, (__native)&TASK->phones[newphid]); |
409 | IPC_SET_ARG3(call.data, (__native)&TASK->phones[newphid]); |
| 417 | 410 | ||