#include <linux/vt.h>
#include <linux/dm-ioctl.h>
#include <linux/reboot.h>
+#include <linux/route.h>
#include "linux_loop.h"
#include "cpu-uname.h"
}
#endif
+#ifdef TARGET_NR_utimensat
#ifdef CONFIG_UTIMENSAT
static int sys_utimensat(int dirfd, const char *pathname,
const struct timespec times[2], int flags)
else
return utimensat(dirfd, pathname, times, flags);
}
-#else
-#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
+#elif defined(__NR_utimensat)
+#define __NR_sys_utimensat __NR_utimensat
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
const struct timespec *,tsp,int,flags)
+#else
+static int sys_utimensat(int dirfd, const char *pathname,
+ const struct timespec times[2], int flags)
+{
+ errno = ENOSYS;
+ return -1;
+}
#endif
-#endif /* CONFIG_UTIMENSAT */
+#endif /* TARGET_NR_utimensat */
#ifdef CONFIG_INOTIFY
#include <sys/inotify.h>
free(vec);
}
-/* do_socket() Must return target values and target errnos. */
-static abi_long do_socket(int domain, int type, int protocol)
+static inline void target_to_host_sock_type(int *type)
{
-#if defined(TARGET_MIPS)
- switch(type) {
+ int host_type = 0;
+ int target_type = *type;
+
+ switch (target_type & TARGET_SOCK_TYPE_MASK) {
case TARGET_SOCK_DGRAM:
- type = SOCK_DGRAM;
+ host_type = SOCK_DGRAM;
break;
case TARGET_SOCK_STREAM:
- type = SOCK_STREAM;
- break;
- case TARGET_SOCK_RAW:
- type = SOCK_RAW;
- break;
- case TARGET_SOCK_RDM:
- type = SOCK_RDM;
- break;
- case TARGET_SOCK_SEQPACKET:
- type = SOCK_SEQPACKET;
+ host_type = SOCK_STREAM;
break;
- case TARGET_SOCK_PACKET:
- type = SOCK_PACKET;
+ default:
+ host_type = target_type & TARGET_SOCK_TYPE_MASK;
break;
}
-#endif
+ if (target_type & TARGET_SOCK_CLOEXEC) {
+ host_type |= SOCK_CLOEXEC;
+ }
+ if (target_type & TARGET_SOCK_NONBLOCK) {
+ host_type |= SOCK_NONBLOCK;
+ }
+ *type = host_type;
+}
+
+/* do_socket() Must return target values and target errnos. */
+static abi_long do_socket(int domain, int type, int protocol)
+{
+ target_to_host_sock_type(&type);
+
if (domain == PF_NETLINK)
return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
return get_errno(socket(domain, type, protocol));
int tab[2];
abi_long ret;
+ target_to_host_sock_type(&type);
+
ret = get_errno(socketpair(domain, type, protocol, tab));
if (!is_error(ret)) {
if (put_user_s32(tab[0], target_tab_addr)
return ret;
}
+static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, abi_long cmd, abi_long arg)
+{
+ const argtype *arg_type = ie->arg_type;
+ const StructEntry *se;
+ const argtype *field_types;
+ const int *dst_offsets, *src_offsets;
+ int target_size;
+ void *argptr;
+ abi_ulong *target_rt_dev_ptr;
+ unsigned long *host_rt_dev_ptr;
+ abi_long ret;
+ int i;
+
+ assert(ie->access == IOC_W);
+ assert(*arg_type == TYPE_PTR);
+ arg_type++;
+ assert(*arg_type == TYPE_STRUCT);
+ target_size = thunk_type_size(arg_type, 0);
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ return -TARGET_EFAULT;
+ }
+ arg_type++;
+ assert(*arg_type == (int)STRUCT_rtentry);
+ se = struct_entries + *arg_type++;
+ assert(se->convert[0] == NULL);
+ /* convert struct here to be able to catch rt_dev string */
+ field_types = se->field_types;
+ dst_offsets = se->field_offsets[THUNK_HOST];
+ src_offsets = se->field_offsets[THUNK_TARGET];
+ for (i = 0; i < se->nb_fields; i++) {
+ if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {
+ assert(*field_types == TYPE_PTRVOID);
+ target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);
+ host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);
+ if (*target_rt_dev_ptr != 0) {
+ *host_rt_dev_ptr = (unsigned long)lock_user_string(
+ tswapal(*target_rt_dev_ptr));
+ if (!*host_rt_dev_ptr) {
+ unlock_user(argptr, arg, 0);
+ return -TARGET_EFAULT;
+ }
+ } else {
+ *host_rt_dev_ptr = 0;
+ }
+ field_types++;
+ continue;
+ }
+ field_types = thunk_convert(buf_temp + dst_offsets[i],
+ argptr + src_offsets[i],
+ field_types, THUNK_HOST);
+ }
+ unlock_user(argptr, arg, 0);
+
+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
+ if (*host_rt_dev_ptr != 0) {
+ unlock_user((void *)*host_rt_dev_ptr,
+ *target_rt_dev_ptr, 0);
+ }
+ return ret;
+}
+
static IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, ...) \
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
env = info->env;
cpu = ENV_GET_CPU(env);
- thread_env = env;
- ts = (TaskState *)thread_env->opaque;
+ thread_cpu = cpu;
+ ts = (TaskState *)env->opaque;
info->tid = gettid();
cpu->host_tid = info->tid;
task_settid(ts);
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8)
{
+#ifdef CONFIG_USE_NPTL
+ CPUState *cpu = ENV_GET_CPU(cpu_env);
+#endif
abi_long ret;
struct stat st;
struct statfs stfs;
switch(num) {
case TARGET_NR_exit:
#ifdef CONFIG_USE_NPTL
- /* In old applications this may be used to implement _exit(2).
- However in threaded applictions it is used for thread termination,
- and _exit_group is used for application termination.
- Do thread termination if we have more then one thread. */
- /* FIXME: This probably breaks if a signal arrives. We should probably
- be disabling signals. */
- if (first_cpu->next_cpu) {
- TaskState *ts;
- CPUArchState **lastp;
- CPUArchState *p;
-
- cpu_list_lock();
- lastp = &first_cpu;
- p = first_cpu;
- while (p && p != (CPUArchState *)cpu_env) {
- lastp = &p->next_cpu;
- p = p->next_cpu;
- }
- /* If we didn't find the CPU for this thread then something is
- horribly wrong. */
- if (!p)
- abort();
- /* Remove the CPU from the list. */
- *lastp = p->next_cpu;
- cpu_list_unlock();
- ts = ((CPUArchState *)cpu_env)->opaque;
- if (ts->child_tidptr) {
- put_user_u32(0, ts->child_tidptr);
- sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
- NULL, NULL, 0);
- }
- thread_env = NULL;
- object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
- g_free(ts);
- pthread_exit(NULL);
- }
+ /* In old applications this may be used to implement _exit(2).
+ However in threaded applictions it is used for thread termination,
+ and _exit_group is used for application termination.
+ Do thread termination if we have more then one thread. */
+ /* FIXME: This probably breaks if a signal arrives. We should probably
+ be disabling signals. */
+ if (first_cpu->next_cpu) {
+ TaskState *ts;
+ CPUState **lastp;
+ CPUState *p;
+
+ cpu_list_lock();
+ lastp = &first_cpu;
+ p = first_cpu;
+ while (p && p != cpu) {
+ lastp = &p->next_cpu;
+ p = p->next_cpu;
+ }
+ /* If we didn't find the CPU for this thread then something is
+ horribly wrong. */
+ if (!p) {
+ abort();
+ }
+ /* Remove the CPU from the list. */
+ *lastp = p->next_cpu;
+ cpu_list_unlock();
+ ts = ((CPUArchState *)cpu_env)->opaque;
+ if (ts->child_tidptr) {
+ put_user_u32(0, ts->child_tidptr);
+ sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
+ NULL, NULL, 0);
+ }
+ thread_cpu = NULL;
+ object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
+ g_free(ts);
+ pthread_exit(NULL);
+ }
#endif
#ifdef TARGET_GPROF
_mcleanup();
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
ret = do_set_thread_area(cpu_env, arg1);
break;
+#elif defined(TARGET_M68K)
+ {
+ TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
+ ts->tp_value = arg1;
+ break;
+ }
#else
goto unimplemented_nowarn;
#endif
case TARGET_NR_get_thread_area:
#if defined(TARGET_I386) && defined(TARGET_ABI32)
ret = do_get_thread_area(cpu_env, arg1);
+ break;
+#elif defined(TARGET_M68K)
+ {
+ TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
+ ret = ts->tp_value;
+ break;
+ }
#else
goto unimplemented_nowarn;
#endif
goto unimplemented_nowarn;
#endif
-#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
+#if defined(TARGET_NR_utimensat)
case TARGET_NR_utimensat:
{
struct timespec *tsp, ts[2];