Revision c2764719 linux-user/syscall.c
b/linux-user/syscall.c | ||
---|---|---|
156 | 156 |
} |
157 | 157 |
|
158 | 158 |
|
159 |
#define __NR_sys_exit __NR_exit |
|
160 | 159 |
#define __NR_sys_uname __NR_uname |
161 | 160 |
#define __NR_sys_faccessat __NR_faccessat |
162 | 161 |
#define __NR_sys_fchmodat __NR_fchmodat |
... | ... | |
198 | 197 |
return -ENOSYS; |
199 | 198 |
} |
200 | 199 |
#endif |
201 |
_syscall1(int,sys_exit,int,status) |
|
202 | 200 |
_syscall1(int,sys_uname,struct new_utsname *,buf) |
203 | 201 |
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat) |
204 | 202 |
_syscall4(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode,int,flags) |
... | ... | |
2936 | 2934 |
nptl_flags = flags; |
2937 | 2935 |
flags &= ~CLONE_NPTL_FLAGS2; |
2938 | 2936 |
|
2939 |
/* TODO: Implement CLONE_CHILD_CLEARTID. */ |
|
2937 |
if (nptl_flags & CLONE_CHILD_CLEARTID) { |
|
2938 |
ts->child_tidptr = child_tidptr; |
|
2939 |
} |
|
2940 |
|
|
2940 | 2941 |
if (nptl_flags & CLONE_SETTLS) |
2941 | 2942 |
cpu_set_tls (new_env, newtls); |
2942 | 2943 |
|
... | ... | |
2961 | 2962 |
sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); |
2962 | 2963 |
|
2963 | 2964 |
ret = pthread_create(&info.thread, &attr, clone_func, &info); |
2965 |
/* TODO: Free new CPU state if thread creation failed. */ |
|
2964 | 2966 |
|
2965 | 2967 |
sigprocmask(SIG_SETMASK, &info.sigmask, NULL); |
2966 | 2968 |
pthread_attr_destroy(&attr); |
... | ... | |
3011 | 3013 |
ts = (TaskState *)env->opaque; |
3012 | 3014 |
if (flags & CLONE_SETTLS) |
3013 | 3015 |
cpu_set_tls (env, newtls); |
3014 |
/* TODO: Implement CLONE_CHILD_CLEARTID. */ |
|
3016 |
if (flags & CLONE_CHILD_CLEARTID) |
|
3017 |
ts->child_tidptr = child_tidptr; |
|
3015 | 3018 |
#endif |
3016 | 3019 |
} else { |
3017 | 3020 |
fork_end(0); |
... | ... | |
3428 | 3431 |
|
3429 | 3432 |
switch(num) { |
3430 | 3433 |
case TARGET_NR_exit: |
3434 |
#ifdef USE_NPTL |
|
3435 |
/* In old applications this may be used to implement _exit(2). |
|
3436 |
However in threaded applictions it is used for thread termination, |
|
3437 |
and _exit_group is used for application termination. |
|
3438 |
Do thread termination if we have more then one thread. */ |
|
3439 |
/* FIXME: This probably breaks if a signal arrives. We should probably |
|
3440 |
be disabling signals. */ |
|
3441 |
if (first_cpu->next_cpu) { |
|
3442 |
CPUState **lastp; |
|
3443 |
CPUState *p; |
|
3444 |
|
|
3445 |
cpu_list_lock(); |
|
3446 |
lastp = &first_cpu; |
|
3447 |
p = first_cpu; |
|
3448 |
while (p && p != (CPUState *)cpu_env) { |
|
3449 |
lastp = &p->next_cpu; |
|
3450 |
p = p->next_cpu; |
|
3451 |
} |
|
3452 |
/* If we didn't find the CPU for this thread then something is |
|
3453 |
horribly wrong. */ |
|
3454 |
if (!p) |
|
3455 |
abort(); |
|
3456 |
/* Remove the CPU from the list. */ |
|
3457 |
*lastp = p->next_cpu; |
|
3458 |
cpu_list_unlock(); |
|
3459 |
TaskState *ts = ((CPUState *)cpu_env)->opaque; |
|
3460 |
if (ts->child_tidptr) { |
|
3461 |
put_user_u32(0, ts->child_tidptr); |
|
3462 |
sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX, |
|
3463 |
NULL, NULL, 0); |
|
3464 |
} |
|
3465 |
/* TODO: Free CPU state. */ |
|
3466 |
pthread_exit(NULL); |
|
3467 |
} |
|
3468 |
#endif |
|
3431 | 3469 |
#ifdef HAVE_GPROF |
3432 | 3470 |
_mcleanup(); |
3433 | 3471 |
#endif |
3434 | 3472 |
gdb_exit(cpu_env, arg1); |
3435 |
/* XXX: should free thread stack and CPU env */ |
|
3436 |
sys_exit(arg1); |
|
3473 |
_exit(arg1); |
|
3437 | 3474 |
ret = 0; /* avoid warning */ |
3438 | 3475 |
break; |
3439 | 3476 |
case TARGET_NR_read: |
Also available in: Unified diff