Changeset 2ba7810 in mainline for generic/src/ipc/sysipc.c
- Timestamp:
- 2006-03-16T12:24:20Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b7dcabb
- Parents:
- d764ddc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/ipc/sysipc.c
rd764ddc r2ba7810 41 41 * on phone, add counter + thread_kill?? 42 42 * 43 * - don't allow userspace app to send system messages 44 */ 43 */ 44 45 /** Return true if the method is a system method */ 46 static inline int is_system_method(__native method) 47 { 48 if (method <= IPC_M_LAST_SYSTEM) 49 return 1; 50 return 0; 51 } 52 53 /** Return true if the message with this method is forwardable 54 * 55 * - some system messages may be forwarded, for some of them 56 * it is useless 57 */ 58 static inline int is_forwardable(__native method) 59 { 60 return 1; 61 } 62 63 /** Find call_t * in call table according to callid 64 * 65 * @return NULL on not found, otherwise pointer to call structure 66 */ 67 static inline call_t * get_call(__native callid) 68 { 69 /* TODO: Traverse list of dispatched calls and find one */ 70 /* TODO: locking of call, ripping it from dispatched calls etc. */ 71 return (call_t *) callid; 72 } 45 73 46 74 /** Return pointer to phone identified by phoneid or NULL if non-existent */ … … 59 87 60 88 /** Allocate new phone slot in current TASK structure */ 61 static int phone_alloc( answerbox_t *callee)89 static int phone_alloc(void) 62 90 { 63 91 int i; … … 66 94 67 95 for (i=0; i < IPC_MAX_PHONES; i++) { 68 if (!TASK->phones[i]. callee) {69 TASK->phones[i]. callee = callee;96 if (!TASK->phones[i].busy) { 97 TASK->phones[i].busy = 1; 70 98 break; 71 99 } … … 83 111 spinlock_lock(&TASK->lock); 84 112 85 ASSERT(TASK->phones[phoneid].callee); 86 87 TASK->phones[phoneid].callee = NULL; 113 ASSERT(TASK->phones[phoneid].busy); 114 115 if (TASK->phones[phoneid].callee) 116 ipc_phone_destroy(&TASK->phones[phoneid]); 117 118 TASK->phones[phoneid].busy = 0; 88 119 spinlock_unlock(&TASK->lock); 120 } 121 122 static void phone_connect(int phoneid, answerbox_t *box) 123 { 124 phone_t *phone = &TASK->phones[phoneid]; 125 126 ipc_phone_connect(phone, box); 89 127 } 90 128 … … 105 143 106 144 /** Interpret process answer as control information */ 107 static inline void answer_preprocess(call_t *answer, call_t *call)145 static inline void answer_preprocess(call_t *answer, ipc_data_t *olddata) 108 146 { 109 147 int phoneid; 110 148 111 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECTTOME) { 149 if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTTOME) { 150 phoneid = IPC_GET_ARG3(*olddata); 112 151 if (IPC_GET_RETVAL(answer->data)) { 113 152 /* The connection was not accepted */ 114 /* TODO...race for multi-threaded process */115 phoneid = IPC_GET_ARG3(call->data);116 153 phone_dealloc(phoneid); 154 } else { 155 /* The connection was accepted */ 156 phone_connect(phoneid,&answer->sender->answerbox); 117 157 } 118 158 } … … 139 179 140 180 if (IPC_GET_METHOD(call->data) == IPC_M_CONNECTTOME) { 141 phoneid = phone_alloc( &call->sender->answerbox);181 phoneid = phone_alloc(); 142 182 if (phoneid < 0) { /* Failed to allocate phone */ 143 183 IPC_SET_RETVAL(call->data, ELIMIT); … … 163 203 phone = get_phone(phoneid); 164 204 if (!phone) 165 return IPC_CALLRET_FATAL; 205 return ENOENT; 206 207 if (is_system_method(method)) 208 return EPERM; 166 209 167 210 ipc_call_init(&call); … … 185 228 phone = get_phone(phoneid); 186 229 if (!phone) 187 return IPC_CALLRET_FATAL;230 return ENOENT; 188 231 189 232 ipc_call_init(&call); 190 233 copy_from_uspace(&call.data, question, sizeof(call.data)); 234 235 if (is_system_method(IPC_GET_METHOD(call.data))) 236 return EPERM; 191 237 192 238 ipc_call_sync(phone, &call); … … 223 269 phone = get_phone(phoneid); 224 270 if (!phone) 271 return IPC_CALLRET_FATAL; 272 273 if (is_system_method(method)) 225 274 return IPC_CALLRET_FATAL; 226 275 … … 256 305 call = ipc_call_alloc(); 257 306 copy_from_uspace(&call->data, data, sizeof(call->data)); 307 308 if (is_system_method(IPC_GET_METHOD(call->data))) { 309 ipc_call_free(call); 310 return EPERM; 311 } 258 312 259 313 ipc_call(phone, call); 260 314 261 315 return (__native) call; 316 } 317 318 /** Forward received call to another destination 319 * 320 * The arg1 and arg2 are changed in the forwarded message 321 */ 322 __native sys_ipc_forward_fast(__native callid, __native phoneid, 323 __native method, __native arg1) 324 { 325 call_t *call; 326 phone_t *phone; 327 328 call = get_call(callid); 329 if (!call) 330 return ENOENT; 331 332 phone = get_phone(phoneid); 333 if (!phone) { 334 IPC_SET_RETVAL(call->data, EFORWARD); 335 ipc_answer(&TASK->answerbox, call); 336 return ENOENT; 337 } 338 339 if (!is_forwardable(IPC_GET_METHOD(call->data))) { 340 IPC_SET_RETVAL(call->data, EFORWARD); 341 ipc_answer(&TASK->answerbox, call); 342 return EPERM; 343 } 344 345 /* Userspace is not allowed to change method of system methods 346 * on forward, allow changing ARG1 and ARG2 by means of method and arg1 347 */ 348 if (is_system_method(IPC_GET_METHOD(call->data))) { 349 IPC_SET_ARG1(call->data, method); 350 IPC_SET_ARG2(call->data, arg1); 351 } else { 352 IPC_SET_METHOD(call->data, method); 353 IPC_SET_ARG1(call->data, arg1); 354 } 355 356 ipc_forward(call, phone->callee, &TASK->answerbox); 357 358 return 0; 262 359 } 263 360 … … 267 364 { 268 365 call_t *call; 269 call_t saved_call;366 ipc_data_t saved_data; 270 367 int preprocess = 0; 271 368 272 /* Check that the user is not sending us answer callid */ 273 ASSERT(! (callid & 1)); 274 /* TODO: Check that the callid is in the dispatch table */ 275 call = (call_t *) callid; 369 call = get_call(callid); 370 if (!call) 371 return ENOENT; 276 372 277 373 if (answer_will_preprocess(call)) { 278 memcpy(&saved_ call.data, &call->data, sizeof(call->data));374 memcpy(&saved_data, &call->data, sizeof(call->data)); 279 375 preprocess = 1; 280 376 } … … 283 379 IPC_SET_ARG1(call->data, arg1); 284 380 IPC_SET_ARG2(call->data, arg2); 381 285 382 if (preprocess) 286 answer_preprocess(call, &saved_ call);383 answer_preprocess(call, &saved_data); 287 384 288 385 ipc_answer(&TASK->answerbox, call); … … 294 391 { 295 392 call_t *call; 296 call_t saved_call;393 ipc_data_t saved_data; 297 394 int preprocess = 0; 298 395 299 /* Check that the user is not sending us answer callid */ 300 ASSERT(! (callid & 1)); 301 /* TODO: Check that the callid is in the dispatch table */ 302 call = (call_t *) callid; 396 call = get_call(callid); 397 if (!call) 398 return ENOENT; 303 399 304 400 if (answer_will_preprocess(call)) { 305 memcpy(&saved_ call.data, &call->data, sizeof(call->data));401 memcpy(&saved_data, &call->data, sizeof(call->data)); 306 402 preprocess = 1; 307 403 } … … 309 405 310 406 if (preprocess) 311 answer_preprocess(call, &saved_ call);407 answer_preprocess(call, &saved_data); 312 408 313 409 ipc_answer(&TASK->answerbox, call); … … 328 424 phone = get_phone(phoneid); 329 425 if (!phone) 330 return IPC_CALLRET_FATAL;426 return ENOENT; 331 427 332 428 ipc_call_init(&call); … … 344 440 } 345 441 442 /** Ask target process to connect me somewhere 443 * 444 * @return phoneid - on success, error otherwise 445 */ 446 __native sys_ipc_connect_me_to(__native phoneid, __native arg1, 447 __native arg2) 448 { 449 call_t call; 450 phone_t *phone; 451 452 phone = get_phone(phoneid); 453 if (!phone) 454 return ENOENT; 455 456 ipc_call_init(&call); 457 IPC_SET_METHOD(call.data, IPC_M_CONNECTMETO); 458 IPC_SET_ARG1(call.data, arg1); 459 IPC_SET_ARG2(call.data, arg2); 460 461 ipc_call_sync(phone, &call); 462 if (!IPC_GET_RETVAL(call.data)) { 463 /* Everybody accepted, we should be connected by now */ 464 } 465 466 return 0; 467 } 468 346 469 /** Wait for incoming ipc call or answer 347 470 * … … 363 486 restart: 364 487 call = ipc_wait_for_call(&TASK->answerbox, flags); 488 printf("Received call %P from sender: %P\n", call, call->sender); 365 489 366 490 if (call->flags & IPC_CALL_ANSWERED) {
Note:
See TracChangeset
for help on using the changeset viewer.