diff --git a/bsd-user/bsd-misc.c b/bsd-user/bsd-misc.c index 68b67f37ba..d1645db46b 100644 --- a/bsd-user/bsd-misc.c +++ b/bsd-user/bsd-misc.c @@ -7,6 +7,11 @@ */ #include "qemu/osdep.h" +#define _WANT_SEMUN +#include +#include +#include +#include #include #include "qemu.h" @@ -33,3 +38,33 @@ abi_long host_to_target_uuid(abi_ulong target_addr, struct uuid *host_uuid) unlock_user_struct(target_uuid, target_addr, 1); return 0; } + +abi_long target_to_host_semarray(int semid, unsigned short **host_array, + abi_ulong target_addr) +{ + abi_long ret; + int nsems, i; + unsigned short *array; + union semun semun; + struct semid_ds semid_ds; + + semun.buf = &semid_ds; + ret = semctl(semid, 0, IPC_STAT, semun); + if (ret == -1) { + return get_errno(ret); + } + nsems = semid_ds.sem_nsems; + *host_array = g_new(unsigned short, nsems); + array = lock_user(VERIFY_READ, target_addr, + nsems * sizeof(unsigned short), 1); + if (array == NULL) { + free(*host_array); + return -TARGET_EFAULT; + } + for (i = 0; i < nsems; i++) { + __get_user((*host_array)[i], array + i); + } + unlock_user(array, target_addr, 0); + + return 0; +}