Revision 1b6b029e linux-user/syscall.c

b/linux-user/syscall.c
762 762
    }
763 763
    return ret;
764 764
}
765

  
766
/* this stack is the equivalent of the kernel stack associated with a
767
   thread/process */
768
#define NEW_STACK_SIZE 8192
769

  
770
static int clone_func(void *arg)
771
{
772
    CPUX86State *env = arg;
773
    cpu_loop(env);
774
    /* never exits */
775
    return 0;
776
}
777

  
778
int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
779
{
780
    int ret;
781
    uint8_t *new_stack;
782
    CPUX86State *new_env;
783
    
784
    if (flags & CLONE_VM) {
785
        if (!newsp)
786
            newsp = env->regs[R_ESP];
787
        new_stack = malloc(NEW_STACK_SIZE);
788
        
789
        /* we create a new CPU instance. */
790
        new_env = cpu_x86_init();
791
        memcpy(new_env, env, sizeof(CPUX86State));
792
        new_env->regs[R_ESP] = newsp;
793
        new_env->regs[R_EAX] = 0;
794
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
795
    } else {
796
        /* if no CLONE_VM, we consider it is a fork */
797
        if ((flags & ~CSIGNAL) != 0)
798
            return -EINVAL;
799
        ret = fork();
800
    }
801
    return ret;
802
}
803

  
765 804
#endif
766 805

  
806

  
767 807
void syscall_init(void)
768 808
{
769 809
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
......
788 828
#ifdef HAVE_GPROF
789 829
        _mcleanup();
790 830
#endif
831
        /* XXX: should free thread stack and CPU env */
791 832
        _exit(arg1);
792 833
        ret = 0; /* avoid warning */
793 834
        break;
......
807 848
        ret = do_brk((char *)arg1);
808 849
        break;
809 850
    case TARGET_NR_fork:
810
        ret = get_errno(fork());
851
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
811 852
        break;
812 853
    case TARGET_NR_waitpid:
813 854
        {
......
1241 1282
    case TARGET_NR_sigreturn:
1242 1283
        goto unimplemented;
1243 1284
    case TARGET_NR_clone:
1244
        goto unimplemented;
1285
        ret = get_errno(do_fork(cpu_env, arg1, arg2));
1286
        break;
1245 1287
    case TARGET_NR_setdomainname:
1246 1288
        ret = get_errno(setdomainname((const char *)arg1, arg2));
1247 1289
        break;
......
1310 1352
    case TARGET_NR_sysfs:
1311 1353
        goto unimplemented;
1312 1354
    case TARGET_NR_personality:
1313
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1355
        ret = get_errno(personality(arg1));
1314 1356
        break;
1315 1357
    case TARGET_NR_afs_syscall:
1316 1358
        goto unimplemented;
......
1447 1489
    case TARGET_NR_sched_get_priority_max:
1448 1490
    case TARGET_NR_sched_get_priority_min:
1449 1491
    case TARGET_NR_sched_rr_get_interval:
1492
        goto unimplemented;
1493
        
1450 1494
    case TARGET_NR_nanosleep:
1495
        {
1496
            struct target_timespec *target_req = (void *)arg1;
1497
            struct target_timespec *target_rem = (void *)arg2;
1498
            struct timespec req, rem;
1499
            req.tv_sec = tswapl(target_req->tv_sec);
1500
            req.tv_nsec = tswapl(target_req->tv_nsec);
1501
            ret = get_errno(nanosleep(&req, &rem));
1502
            if (target_rem) {
1503
                target_rem->tv_sec = tswapl(rem.tv_sec);
1504
                target_rem->tv_nsec = tswapl(rem.tv_nsec);
1505
            }
1506
        }
1507
        break;
1508

  
1451 1509
    case TARGET_NR_mremap:
1452 1510
    case TARGET_NR_setresuid:
1453 1511
    case TARGET_NR_getresuid:
......
1481 1539
    case TARGET_NR_getpmsg:
1482 1540
    case TARGET_NR_putpmsg:
1483 1541
    case TARGET_NR_vfork:
1484
        ret = get_errno(vfork());
1542
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
1485 1543
        break;
1486 1544
    case TARGET_NR_ugetrlimit:
1487 1545
    case TARGET_NR_truncate64:

Also available in: Unified diff