Subversion Repositories HelenOS

Rev

Rev 3001 | Rev 3149 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3001 Rev 3004
Line 48... Line 48...
48
#include <panic.h>
48
#include <panic.h>
49
#include <adt/avl.h>
49
#include <adt/avl.h>
50
#include <adt/btree.h>
50
#include <adt/btree.h>
51
#include <adt/list.h>
51
#include <adt/list.h>
52
#include <ipc/ipc.h>
52
#include <ipc/ipc.h>
-
 
53
#include <ipc/ipcrsc.h>
53
#include <security/cap.h>
54
#include <security/cap.h>
54
#include <memstr.h>
55
#include <memstr.h>
55
#include <print.h>
56
#include <print.h>
56
#include <lib/elf.h>
57
#include <lib/elf.h>
57
#include <errno.h>
58
#include <errno.h>
Line 321... Line 322...
321
    return EOK;
322
    return EOK;
322
}
323
}
323
 
324
 
324
/** Create a task from the program loader image.
325
/** Create a task from the program loader image.
325
 *
326
 *
326
 * @param program_addr Address of program executable image.
-
 
327
 * @param name Program name.
327
 * @param name Program name.
-
 
328
 * @param t Buffer for storing pointer to the newly created task.
328
 *
329
 *
329
 * @return Task of the running program or NULL on error.
330
 * @return Task of the running program or NULL on error.
330
 */
331
 */
331
task_t *task_create_from_loader(char *name)
332
int task_create_from_loader(char *name, task_t **t)
332
{
333
{
333
    as_t *as;
334
    as_t *as;
334
    unsigned int rc;
335
    unsigned int rc;
-
 
336
    void *loader;
335
 
337
 
336
    as = as_create(0);
338
    as = as_create(0);
337
    ASSERT(as);
339
    ASSERT(as);
338
 
340
 
-
 
341
    loader = program_loader;
-
 
342
    if (!loader) return ENOENT;
-
 
343
 
339
    rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER);
344
    rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER);
340
    if (rc != EE_OK) {
345
    if (rc != EE_OK) {
341
        as_destroy(as);
346
        as_destroy(as);
342
        return NULL;
347
        return ENOENT;
343
    }
348
    }
344
 
349
 
345
    return task_create_from_as(
350
    *t = task_create_from_as(
346
        as, ((elf_header_t *) program_loader)->e_entry, name); 
351
        as, ((elf_header_t *) program_loader)->e_entry, name); 
-
 
352
 
-
 
353
    return EOK;
347
}
354
}
348
 
355
 
349
/** Make task ready.
356
/** Make task ready.
350
 *
357
 *
351
 * Switch task's thread to the ready state.
358
 * Switch task's thread to the ready state.
Line 377... Line 384...
377
        sizeof(TASK->taskid));
384
        sizeof(TASK->taskid));
378
}
385
}
379
 
386
 
380
/** Syscall for creating a new task from userspace.
387
/** Syscall for creating a new task from userspace.
381
 *
388
 *
382
 * Creates a new task from the program loader image and stores its
389
 * Creates a new task from the program loader image, connects a phone
383
 * task id into the provided buffer.
390
 * to it and stores the phone id into the provided buffer.
384
 *
391
 *
385
 * @param uspace_task_id Userspace address of 8-byte buffer where to store
392
 * @param uspace_phone_id Userspace address where to store the phone id.
386
 * current task ID.
-
 
387
 *
393
 *
388
 * @return 0 on success or an error code from @ref errno.h.
394
 * @return 0 on success or an error code from @ref errno.h.
389
 */
395
 */
390
unative_t sys_task_spawn(task_id_t *uspace_task_id)
396
unative_t sys_task_spawn(int *uspace_phone_id)
391
{
397
{
392
    task_t *t;
398
    task_t *t;
393
    task_id_t fake_id;
399
    int fake_id;
394
    int rc;
400
    int rc;
-
 
401
    int phone_id;
-
 
402
 
-
 
403
    fake_id = 0;
395
 
404
 
396
    /* Before we even try creating the task, see if we can write the id */
405
    /* Before we even try creating the task, see if we can write the id */
397
    rc = (unative_t) copy_to_uspace(uspace_task_id, &fake_id,
406
    rc = (unative_t) copy_to_uspace(uspace_phone_id, &fake_id,
398
        sizeof(fake_id));
407
        sizeof(fake_id));
399
    if (rc != 0)
408
    if (rc != 0)
400
        return rc;
409
        return rc;
401
 
410
 
-
 
411
    phone_id = phone_alloc();
-
 
412
    if (phone_id < 0)
-
 
413
        return ELIMIT;
-
 
414
 
402
    t = task_create_from_loader("loader");
415
    rc = task_create_from_loader("loader", &t);
-
 
416
    if (rc != 0)
-
 
417
        return rc;
-
 
418
 
-
 
419
    phone_connect(phone_id, &t->answerbox);
403
 
420
 
404
    /* No need to aquire lock before task_ready() */
421
    /* No need to aquire lock before task_ready() */
405
    rc = (unative_t) copy_to_uspace(uspace_task_id, &t->taskid,
422
    rc = (unative_t) copy_to_uspace(uspace_phone_id, &phone_id,
406
        sizeof(t->taskid));
423
        sizeof(phone_id));
407
    if (rc != 0) {
424
    if (rc != 0) {
408
        /* Ooops */
425
        /* Ooops */
-
 
426
        ipc_phone_hangup(&TASK->phones[phone_id]);
409
        task_kill(t->taskid);
427
        task_kill(t->taskid);
410
        return rc;
428
        return rc;
411
    }
429
    }
412
 
430
 
413
    task_ready(t);
431
    task_ready(t);