Subversion Repositories HelenOS

Rev

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