Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 95b33b2f

History | View | Annotate | Download (248.7 kB)

1 31e31b8a bellard
/*
2 31e31b8a bellard
 *  Linux syscalls
3 5fafdf24 ths
 *
4 31e31b8a bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 31e31b8a bellard
 *
6 31e31b8a bellard
 *  This program is free software; you can redistribute it and/or modify
7 31e31b8a bellard
 *  it under the terms of the GNU General Public License as published by
8 31e31b8a bellard
 *  the Free Software Foundation; either version 2 of the License, or
9 31e31b8a bellard
 *  (at your option) any later version.
10 31e31b8a bellard
 *
11 31e31b8a bellard
 *  This program is distributed in the hope that it will be useful,
12 31e31b8a bellard
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 31e31b8a bellard
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 31e31b8a bellard
 *  GNU General Public License for more details.
15 31e31b8a bellard
 *
16 31e31b8a bellard
 *  You should have received a copy of the GNU General Public License
17 8167ee88 Blue Swirl
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18 31e31b8a bellard
 */
19 d5b3a9b6 Eduardo Habkost
#define _ATFILE_SOURCE
20 31e31b8a bellard
#include <stdlib.h>
21 31e31b8a bellard
#include <stdio.h>
22 31e31b8a bellard
#include <stdarg.h>
23 04369ff2 bellard
#include <string.h>
24 31e31b8a bellard
#include <elf.h>
25 31e31b8a bellard
#include <endian.h>
26 31e31b8a bellard
#include <errno.h>
27 31e31b8a bellard
#include <unistd.h>
28 31e31b8a bellard
#include <fcntl.h>
29 7854b056 bellard
#include <time.h>
30 82e671d9 pbrook
#include <limits.h>
31 31e31b8a bellard
#include <sys/types.h>
32 d08d3bb8 ths
#include <sys/ipc.h>
33 d08d3bb8 ths
#include <sys/msg.h>
34 31e31b8a bellard
#include <sys/wait.h>
35 31e31b8a bellard
#include <sys/time.h>
36 31e31b8a bellard
#include <sys/stat.h>
37 31e31b8a bellard
#include <sys/mount.h>
38 39b9aae1 ths
#include <sys/prctl.h>
39 31e31b8a bellard
#include <sys/resource.h>
40 31e31b8a bellard
#include <sys/mman.h>
41 31e31b8a bellard
#include <sys/swap.h>
42 31e31b8a bellard
#include <signal.h>
43 31e31b8a bellard
#include <sched.h>
44 60e99246 Aurelien Jarno
#ifdef __ia64__
45 60e99246 Aurelien Jarno
int __clone2(int (*fn)(void *), void *child_stack_base,
46 60e99246 Aurelien Jarno
             size_t stack_size, int flags, void *arg, ...);
47 60e99246 Aurelien Jarno
#endif
48 31e31b8a bellard
#include <sys/socket.h>
49 607175e0 aurel32
#include <sys/un.h>
50 31e31b8a bellard
#include <sys/uio.h>
51 9de5e440 bellard
#include <sys/poll.h>
52 32f36bce bellard
#include <sys/times.h>
53 8853f86e bellard
#include <sys/shm.h>
54 fa294816 ths
#include <sys/sem.h>
55 56c8f68f bellard
#include <sys/statfs.h>
56 ebc05488 bellard
#include <utime.h>
57 a5448a7d bellard
#include <sys/sysinfo.h>
58 3b3f24ad aurel32
#include <sys/utsname.h>
59 72f03900 bellard
//#include <sys/user.h>
60 8853f86e bellard
#include <netinet/ip.h>
61 7854b056 bellard
#include <netinet/tcp.h>
62 86fcd946 Laurent Vivier
#include <linux/wireless.h>
63 0b6d3ae0 aurel32
#include <qemu-common.h>
64 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
65 6d946cda aurel32
#include <sys/gmon.h>
66 6d946cda aurel32
#endif
67 c2882b96 Riku Voipio
#ifdef CONFIG_EVENTFD
68 c2882b96 Riku Voipio
#include <sys/eventfd.h>
69 c2882b96 Riku Voipio
#endif
70 3b6edd16 Peter Maydell
#ifdef CONFIG_EPOLL
71 3b6edd16 Peter Maydell
#include <sys/epoll.h>
72 3b6edd16 Peter Maydell
#endif
73 31e31b8a bellard
74 31e31b8a bellard
#define termios host_termios
75 31e31b8a bellard
#define winsize host_winsize
76 31e31b8a bellard
#define termio host_termio
77 04369ff2 bellard
#define sgttyb host_sgttyb /* same as target */
78 04369ff2 bellard
#define tchars host_tchars /* same as target */
79 04369ff2 bellard
#define ltchars host_ltchars /* same as target */
80 31e31b8a bellard
81 31e31b8a bellard
#include <linux/termios.h>
82 31e31b8a bellard
#include <linux/unistd.h>
83 31e31b8a bellard
#include <linux/utsname.h>
84 31e31b8a bellard
#include <linux/cdrom.h>
85 31e31b8a bellard
#include <linux/hdreg.h>
86 31e31b8a bellard
#include <linux/soundcard.h>
87 19b84f3c bellard
#include <linux/kd.h>
88 8fbd6b52 balrog
#include <linux/mtio.h>
89 350d1779 Martin Mohring
#include <linux/fs.h>
90 dace20dc Peter Maydell
#if defined(CONFIG_FIEMAP)
91 285da2b9 Peter Maydell
#include <linux/fiemap.h>
92 dace20dc Peter Maydell
#endif
93 f7680a55 Ulrich Hecht
#include <linux/fb.h>
94 f7680a55 Ulrich Hecht
#include <linux/vt.h>
95 d7e4036e pbrook
#include "linux_loop.h"
96 da79030f Loïc Minier
#include "cpu-uname.h"
97 31e31b8a bellard
98 3ef693a0 bellard
#include "qemu.h"
99 526ccb7a balrog
#include "qemu-common.h"
100 31e31b8a bellard
101 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
102 d865bab5 pbrook
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
103 d865bab5 pbrook
    CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
104 d865bab5 pbrook
#else
105 d865bab5 pbrook
/* XXX: Hardcode the above values.  */
106 d865bab5 pbrook
#define CLONE_NPTL_FLAGS2 0
107 30813cea pbrook
#endif
108 30813cea pbrook
109 72f03900 bellard
//#define DEBUG
110 31e31b8a bellard
111 1a9353d2 bellard
//#include <linux/msdos_fs.h>
112 6556a833 aurel32
#define        VFAT_IOCTL_READDIR_BOTH                _IOR('r', 1, struct linux_dirent [2])
113 6556a833 aurel32
#define        VFAT_IOCTL_READDIR_SHORT        _IOR('r', 2, struct linux_dirent [2])
114 1a9353d2 bellard
115 70a194b9 bellard
116 70a194b9 bellard
#undef _syscall0
117 70a194b9 bellard
#undef _syscall1
118 70a194b9 bellard
#undef _syscall2
119 70a194b9 bellard
#undef _syscall3
120 70a194b9 bellard
#undef _syscall4
121 70a194b9 bellard
#undef _syscall5
122 83fcb515 bellard
#undef _syscall6
123 70a194b9 bellard
124 83fcb515 bellard
#define _syscall0(type,name)                \
125 8fcd3692 blueswir1
static type name (void)                        \
126 83fcb515 bellard
{                                        \
127 83fcb515 bellard
        return syscall(__NR_##name);        \
128 83fcb515 bellard
}
129 70a194b9 bellard
130 83fcb515 bellard
#define _syscall1(type,name,type1,arg1)                \
131 8fcd3692 blueswir1
static type name (type1 arg1)                        \
132 83fcb515 bellard
{                                                \
133 83fcb515 bellard
        return syscall(__NR_##name, arg1);        \
134 70a194b9 bellard
}
135 70a194b9 bellard
136 83fcb515 bellard
#define _syscall2(type,name,type1,arg1,type2,arg2)        \
137 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2)                \
138 83fcb515 bellard
{                                                        \
139 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2);        \
140 70a194b9 bellard
}
141 70a194b9 bellard
142 83fcb515 bellard
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)        \
143 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3)                \
144 83fcb515 bellard
{                                                                \
145 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3);                \
146 70a194b9 bellard
}
147 70a194b9 bellard
148 83fcb515 bellard
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)        \
149 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4)                        \
150 83fcb515 bellard
{                                                                                \
151 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4);                        \
152 70a194b9 bellard
}
153 70a194b9 bellard
154 83fcb515 bellard
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
155 83fcb515 bellard
                  type5,arg5)                                                        \
156 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5)        \
157 83fcb515 bellard
{                                                                                \
158 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5);                \
159 70a194b9 bellard
}
160 70a194b9 bellard
161 83fcb515 bellard
162 83fcb515 bellard
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,        \
163 83fcb515 bellard
                  type5,arg5,type6,arg6)                                        \
164 8fcd3692 blueswir1
static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,        \
165 8fcd3692 blueswir1
                  type6 arg6)                                                        \
166 83fcb515 bellard
{                                                                                \
167 83fcb515 bellard
        return syscall(__NR_##name, arg1, arg2, arg3, arg4, arg5, arg6);        \
168 70a194b9 bellard
}
169 83fcb515 bellard
170 70a194b9 bellard
171 31e31b8a bellard
#define __NR_sys_uname __NR_uname
172 92a34c10 ths
#define __NR_sys_faccessat __NR_faccessat
173 814d7977 ths
#define __NR_sys_fchmodat __NR_fchmodat
174 ccfa72b7 ths
#define __NR_sys_fchownat __NR_fchownat
175 6a24a778 balrog
#define __NR_sys_fstatat64 __NR_fstatat64
176 ac8a6556 balrog
#define __NR_sys_futimesat __NR_futimesat
177 72f03900 bellard
#define __NR_sys_getcwd1 __NR_getcwd
178 72f03900 bellard
#define __NR_sys_getdents __NR_getdents
179 dab2ed99 bellard
#define __NR_sys_getdents64 __NR_getdents64
180 c6cda17a ths
#define __NR_sys_getpriority __NR_getpriority
181 64f0ce4c ths
#define __NR_sys_linkat __NR_linkat
182 4472ad0d ths
#define __NR_sys_mkdirat __NR_mkdirat
183 75ac37a0 ths
#define __NR_sys_mknodat __NR_mknodat
184 9d33b76b aurel32
#define __NR_sys_newfstatat __NR_newfstatat
185 82424832 ths
#define __NR_sys_openat __NR_openat
186 5e0ccb18 ths
#define __NR_sys_readlinkat __NR_readlinkat
187 722183f6 ths
#define __NR_sys_renameat __NR_renameat
188 66fb9763 bellard
#define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
189 f0b6243d ths
#define __NR_sys_symlinkat __NR_symlinkat
190 7494b0f9 ths
#define __NR_sys_syslog __NR_syslog
191 71455574 ths
#define __NR_sys_tgkill __NR_tgkill
192 4cae1d16 ths
#define __NR_sys_tkill __NR_tkill
193 8170f56b ths
#define __NR_sys_unlinkat __NR_unlinkat
194 9007f0ef ths
#define __NR_sys_utimensat __NR_utimensat
195 bd0c5661 pbrook
#define __NR_sys_futex __NR_futex
196 39b59763 aurel32
#define __NR_sys_inotify_init __NR_inotify_init
197 39b59763 aurel32
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
198 39b59763 aurel32
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
199 31e31b8a bellard
200 42a39fbe Alexander Graf
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
201 42a39fbe Alexander Graf
    defined(__s390x__)
202 9af9eaaa bellard
#define __NR__llseek __NR_lseek
203 9af9eaaa bellard
#endif
204 9af9eaaa bellard
205 72f03900 bellard
#ifdef __NR_gettid
206 31e31b8a bellard
_syscall0(int, gettid)
207 72f03900 bellard
#else
208 0da46a6e ths
/* This is a replacement for the host gettid() and must return a host
209 0da46a6e ths
   errno. */
210 72f03900 bellard
static int gettid(void) {
211 72f03900 bellard
    return -ENOSYS;
212 72f03900 bellard
}
213 72f03900 bellard
#endif
214 3b3f24ad aurel32
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
215 3b3f24ad aurel32
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
216 3b3f24ad aurel32
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
217 3b3f24ad aurel32
#endif
218 3b3f24ad aurel32
_syscall2(int, sys_getpriority, int, which, int, who);
219 d35b261c Richard Henderson
#if defined(TARGET_NR__llseek) && defined(__NR_llseek)
220 3b3f24ad aurel32
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
221 3b3f24ad aurel32
          loff_t *, res, uint, wh);
222 3b3f24ad aurel32
#endif
223 3b3f24ad aurel32
_syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
224 3b3f24ad aurel32
_syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
225 3b3f24ad aurel32
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
226 3b3f24ad aurel32
_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
227 3b3f24ad aurel32
#endif
228 3b3f24ad aurel32
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
229 3b3f24ad aurel32
_syscall2(int,sys_tkill,int,tid,int,sig)
230 3b3f24ad aurel32
#endif
231 3b3f24ad aurel32
#ifdef __NR_exit_group
232 3b3f24ad aurel32
_syscall1(int,exit_group,int,error_code)
233 3b3f24ad aurel32
#endif
234 3b3f24ad aurel32
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
235 3b3f24ad aurel32
_syscall1(int,set_tid_address,int *,tidptr)
236 3b3f24ad aurel32
#endif
237 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
238 3b3f24ad aurel32
#if defined(TARGET_NR_futex) && defined(__NR_futex)
239 3b3f24ad aurel32
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
240 3b3f24ad aurel32
          const struct timespec *,timeout,int *,uaddr2,int,val3)
241 3b3f24ad aurel32
#endif
242 3b3f24ad aurel32
#endif
243 737de1d1 Mike Frysinger
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
244 737de1d1 Mike Frysinger
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
245 737de1d1 Mike Frysinger
          unsigned long *, user_mask_ptr);
246 737de1d1 Mike Frysinger
#define __NR_sys_sched_setaffinity __NR_sched_setaffinity
247 737de1d1 Mike Frysinger
_syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
248 737de1d1 Mike Frysinger
          unsigned long *, user_mask_ptr);
249 3b3f24ad aurel32
250 3b3f24ad aurel32
static bitmask_transtbl fcntl_flags_tbl[] = {
251 3b3f24ad aurel32
  { TARGET_O_ACCMODE,   TARGET_O_WRONLY,    O_ACCMODE,   O_WRONLY,    },
252 3b3f24ad aurel32
  { TARGET_O_ACCMODE,   TARGET_O_RDWR,      O_ACCMODE,   O_RDWR,      },
253 3b3f24ad aurel32
  { TARGET_O_CREAT,     TARGET_O_CREAT,     O_CREAT,     O_CREAT,     },
254 3b3f24ad aurel32
  { TARGET_O_EXCL,      TARGET_O_EXCL,      O_EXCL,      O_EXCL,      },
255 3b3f24ad aurel32
  { TARGET_O_NOCTTY,    TARGET_O_NOCTTY,    O_NOCTTY,    O_NOCTTY,    },
256 3b3f24ad aurel32
  { TARGET_O_TRUNC,     TARGET_O_TRUNC,     O_TRUNC,     O_TRUNC,     },
257 3b3f24ad aurel32
  { TARGET_O_APPEND,    TARGET_O_APPEND,    O_APPEND,    O_APPEND,    },
258 3b3f24ad aurel32
  { TARGET_O_NONBLOCK,  TARGET_O_NONBLOCK,  O_NONBLOCK,  O_NONBLOCK,  },
259 3b3f24ad aurel32
  { TARGET_O_SYNC,      TARGET_O_SYNC,      O_SYNC,      O_SYNC,      },
260 3b3f24ad aurel32
  { TARGET_FASYNC,      TARGET_FASYNC,      FASYNC,      FASYNC,      },
261 3b3f24ad aurel32
  { TARGET_O_DIRECTORY, TARGET_O_DIRECTORY, O_DIRECTORY, O_DIRECTORY, },
262 3b3f24ad aurel32
  { TARGET_O_NOFOLLOW,  TARGET_O_NOFOLLOW,  O_NOFOLLOW,  O_NOFOLLOW,  },
263 3b3f24ad aurel32
  { TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
264 3b3f24ad aurel32
#if defined(O_DIRECT)
265 3b3f24ad aurel32
  { TARGET_O_DIRECT,    TARGET_O_DIRECT,    O_DIRECT,    O_DIRECT,    },
266 3b3f24ad aurel32
#endif
267 3b3f24ad aurel32
  { 0, 0, 0, 0 }
268 3b3f24ad aurel32
};
269 3b3f24ad aurel32
270 3b3f24ad aurel32
#define COPY_UTSNAME_FIELD(dest, src) \
271 3b3f24ad aurel32
  do { \
272 3b3f24ad aurel32
      /* __NEW_UTS_LEN doesn't include terminating null */ \
273 3b3f24ad aurel32
      (void) strncpy((dest), (src), __NEW_UTS_LEN); \
274 3b3f24ad aurel32
      (dest)[__NEW_UTS_LEN] = '\0'; \
275 3b3f24ad aurel32
  } while (0)
276 3b3f24ad aurel32
277 3b3f24ad aurel32
static int sys_uname(struct new_utsname *buf)
278 3b3f24ad aurel32
{
279 3b3f24ad aurel32
  struct utsname uts_buf;
280 3b3f24ad aurel32
281 3b3f24ad aurel32
  if (uname(&uts_buf) < 0)
282 3b3f24ad aurel32
      return (-1);
283 3b3f24ad aurel32
284 3b3f24ad aurel32
  /*
285 3b3f24ad aurel32
   * Just in case these have some differences, we
286 3b3f24ad aurel32
   * translate utsname to new_utsname (which is the
287 3b3f24ad aurel32
   * struct linux kernel uses).
288 3b3f24ad aurel32
   */
289 3b3f24ad aurel32
290 67bd9ede Stefan Weil
  memset(buf, 0, sizeof(*buf));
291 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->sysname, uts_buf.sysname);
292 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->nodename, uts_buf.nodename);
293 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->release, uts_buf.release);
294 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->version, uts_buf.version);
295 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->machine, uts_buf.machine);
296 3b3f24ad aurel32
#ifdef _GNU_SOURCE
297 3b3f24ad aurel32
  COPY_UTSNAME_FIELD(buf->domainname, uts_buf.domainname);
298 3b3f24ad aurel32
#endif
299 3b3f24ad aurel32
  return (0);
300 3b3f24ad aurel32
301 3b3f24ad aurel32
#undef COPY_UTSNAME_FIELD
302 3b3f24ad aurel32
}
303 3b3f24ad aurel32
304 3b3f24ad aurel32
static int sys_getcwd1(char *buf, size_t size)
305 3b3f24ad aurel32
{
306 3b3f24ad aurel32
  if (getcwd(buf, size) == NULL) {
307 3b3f24ad aurel32
      /* getcwd() sets errno */
308 3b3f24ad aurel32
      return (-1);
309 3b3f24ad aurel32
  }
310 aaf4ad39 aurel32
  return strlen(buf)+1;
311 3b3f24ad aurel32
}
312 3b3f24ad aurel32
313 3b3f24ad aurel32
#ifdef CONFIG_ATFILE
314 3b3f24ad aurel32
/*
315 3b3f24ad aurel32
 * Host system seems to have atfile syscall stubs available.  We
316 3b3f24ad aurel32
 * now enable them one by one as specified by target syscall_nr.h.
317 3b3f24ad aurel32
 */
318 3b3f24ad aurel32
319 3b3f24ad aurel32
#ifdef TARGET_NR_faccessat
320 465c9f06 aurel32
static int sys_faccessat(int dirfd, const char *pathname, int mode)
321 3b3f24ad aurel32
{
322 465c9f06 aurel32
  return (faccessat(dirfd, pathname, mode, 0));
323 3b3f24ad aurel32
}
324 3b3f24ad aurel32
#endif
325 3b3f24ad aurel32
#ifdef TARGET_NR_fchmodat
326 465c9f06 aurel32
static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
327 3b3f24ad aurel32
{
328 465c9f06 aurel32
  return (fchmodat(dirfd, pathname, mode, 0));
329 3b3f24ad aurel32
}
330 3b3f24ad aurel32
#endif
331 0c866a7e Riku Voipio
#if defined(TARGET_NR_fchownat)
332 3b3f24ad aurel32
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
333 3b3f24ad aurel32
    gid_t group, int flags)
334 3b3f24ad aurel32
{
335 3b3f24ad aurel32
  return (fchownat(dirfd, pathname, owner, group, flags));
336 3b3f24ad aurel32
}
337 3b3f24ad aurel32
#endif
338 3b3f24ad aurel32
#ifdef __NR_fstatat64
339 3b3f24ad aurel32
static int sys_fstatat64(int dirfd, const char *pathname, struct stat *buf,
340 3b3f24ad aurel32
    int flags)
341 3b3f24ad aurel32
{
342 3b3f24ad aurel32
  return (fstatat(dirfd, pathname, buf, flags));
343 3b3f24ad aurel32
}
344 3b3f24ad aurel32
#endif
345 3b3f24ad aurel32
#ifdef __NR_newfstatat
346 3b3f24ad aurel32
static int sys_newfstatat(int dirfd, const char *pathname, struct stat *buf,
347 3b3f24ad aurel32
    int flags)
348 3b3f24ad aurel32
{
349 3b3f24ad aurel32
  return (fstatat(dirfd, pathname, buf, flags));
350 3b3f24ad aurel32
}
351 3b3f24ad aurel32
#endif
352 3b3f24ad aurel32
#ifdef TARGET_NR_futimesat
353 3b3f24ad aurel32
static int sys_futimesat(int dirfd, const char *pathname,
354 3b3f24ad aurel32
    const struct timeval times[2])
355 3b3f24ad aurel32
{
356 3b3f24ad aurel32
  return (futimesat(dirfd, pathname, times));
357 3b3f24ad aurel32
}
358 3b3f24ad aurel32
#endif
359 3b3f24ad aurel32
#ifdef TARGET_NR_linkat
360 3b3f24ad aurel32
static int sys_linkat(int olddirfd, const char *oldpath,
361 3b3f24ad aurel32
    int newdirfd, const char *newpath, int flags)
362 3b3f24ad aurel32
{
363 3b3f24ad aurel32
  return (linkat(olddirfd, oldpath, newdirfd, newpath, flags));
364 3b3f24ad aurel32
}
365 3b3f24ad aurel32
#endif
366 3b3f24ad aurel32
#ifdef TARGET_NR_mkdirat
367 3b3f24ad aurel32
static int sys_mkdirat(int dirfd, const char *pathname, mode_t mode)
368 3b3f24ad aurel32
{
369 3b3f24ad aurel32
  return (mkdirat(dirfd, pathname, mode));
370 3b3f24ad aurel32
}
371 3b3f24ad aurel32
#endif
372 3b3f24ad aurel32
#ifdef TARGET_NR_mknodat
373 3b3f24ad aurel32
static int sys_mknodat(int dirfd, const char *pathname, mode_t mode,
374 3b3f24ad aurel32
    dev_t dev)
375 3b3f24ad aurel32
{
376 3b3f24ad aurel32
  return (mknodat(dirfd, pathname, mode, dev));
377 3b3f24ad aurel32
}
378 3b3f24ad aurel32
#endif
379 3b3f24ad aurel32
#ifdef TARGET_NR_openat
380 3b3f24ad aurel32
static int sys_openat(int dirfd, const char *pathname, int flags, ...)
381 3b3f24ad aurel32
{
382 3b3f24ad aurel32
  /*
383 3b3f24ad aurel32
   * open(2) has extra parameter 'mode' when called with
384 3b3f24ad aurel32
   * flag O_CREAT.
385 3b3f24ad aurel32
   */
386 3b3f24ad aurel32
  if ((flags & O_CREAT) != 0) {
387 3b3f24ad aurel32
      va_list ap;
388 3b3f24ad aurel32
      mode_t mode;
389 3b3f24ad aurel32
390 3b3f24ad aurel32
      /*
391 3b3f24ad aurel32
       * Get the 'mode' parameter and translate it to
392 3b3f24ad aurel32
       * host bits.
393 3b3f24ad aurel32
       */
394 3b3f24ad aurel32
      va_start(ap, flags);
395 3b3f24ad aurel32
      mode = va_arg(ap, mode_t);
396 3b3f24ad aurel32
      mode = target_to_host_bitmask(mode, fcntl_flags_tbl);
397 3b3f24ad aurel32
      va_end(ap);
398 3b3f24ad aurel32
399 3b3f24ad aurel32
      return (openat(dirfd, pathname, flags, mode));
400 3b3f24ad aurel32
  }
401 3b3f24ad aurel32
  return (openat(dirfd, pathname, flags));
402 3b3f24ad aurel32
}
403 3b3f24ad aurel32
#endif
404 3b3f24ad aurel32
#ifdef TARGET_NR_readlinkat
405 3b3f24ad aurel32
static int sys_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz)
406 3b3f24ad aurel32
{
407 3b3f24ad aurel32
  return (readlinkat(dirfd, pathname, buf, bufsiz));
408 3b3f24ad aurel32
}
409 3b3f24ad aurel32
#endif
410 3b3f24ad aurel32
#ifdef TARGET_NR_renameat
411 3b3f24ad aurel32
static int sys_renameat(int olddirfd, const char *oldpath,
412 3b3f24ad aurel32
    int newdirfd, const char *newpath)
413 3b3f24ad aurel32
{
414 3b3f24ad aurel32
  return (renameat(olddirfd, oldpath, newdirfd, newpath));
415 3b3f24ad aurel32
}
416 3b3f24ad aurel32
#endif
417 3b3f24ad aurel32
#ifdef TARGET_NR_symlinkat
418 3b3f24ad aurel32
static int sys_symlinkat(const char *oldpath, int newdirfd, const char *newpath)
419 3b3f24ad aurel32
{
420 3b3f24ad aurel32
  return (symlinkat(oldpath, newdirfd, newpath));
421 3b3f24ad aurel32
}
422 3b3f24ad aurel32
#endif
423 3b3f24ad aurel32
#ifdef TARGET_NR_unlinkat
424 3b3f24ad aurel32
static int sys_unlinkat(int dirfd, const char *pathname, int flags)
425 3b3f24ad aurel32
{
426 3b3f24ad aurel32
  return (unlinkat(dirfd, pathname, flags));
427 3b3f24ad aurel32
}
428 3b3f24ad aurel32
#endif
429 3b3f24ad aurel32
#else /* !CONFIG_ATFILE */
430 3b3f24ad aurel32
431 3b3f24ad aurel32
/*
432 3b3f24ad aurel32
 * Try direct syscalls instead
433 3b3f24ad aurel32
 */
434 92a34c10 ths
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
435 465c9f06 aurel32
_syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
436 92a34c10 ths
#endif
437 814d7977 ths
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
438 465c9f06 aurel32
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
439 814d7977 ths
#endif
440 0c866a7e Riku Voipio
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
441 ccfa72b7 ths
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
442 ccfa72b7 ths
          uid_t,owner,gid_t,group,int,flags)
443 ccfa72b7 ths
#endif
444 9d33b76b aurel32
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
445 9d33b76b aurel32
        defined(__NR_fstatat64)
446 6a24a778 balrog
_syscall4(int,sys_fstatat64,int,dirfd,const char *,pathname,
447 6a24a778 balrog
          struct stat *,buf,int,flags)
448 6a24a778 balrog
#endif
449 ac8a6556 balrog
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
450 ac8a6556 balrog
_syscall3(int,sys_futimesat,int,dirfd,const char *,pathname,
451 ac8a6556 balrog
         const struct timeval *,times)
452 ac8a6556 balrog
#endif
453 3b3f24ad aurel32
#if (defined(TARGET_NR_newfstatat) || defined(TARGET_NR_fstatat64) ) && \
454 3b3f24ad aurel32
        defined(__NR_newfstatat)
455 3b3f24ad aurel32
_syscall4(int,sys_newfstatat,int,dirfd,const char *,pathname,
456 3b3f24ad aurel32
          struct stat *,buf,int,flags)
457 8fcd3692 blueswir1
#endif
458 64f0ce4c ths
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
459 64f0ce4c ths
_syscall5(int,sys_linkat,int,olddirfd,const char *,oldpath,
460 3b3f24ad aurel32
      int,newdirfd,const char *,newpath,int,flags)
461 64f0ce4c ths
#endif
462 4472ad0d ths
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
463 4472ad0d ths
_syscall3(int,sys_mkdirat,int,dirfd,const char *,pathname,mode_t,mode)
464 4472ad0d ths
#endif
465 75ac37a0 ths
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
466 75ac37a0 ths
_syscall4(int,sys_mknodat,int,dirfd,const char *,pathname,
467 75ac37a0 ths
          mode_t,mode,dev_t,dev)
468 75ac37a0 ths
#endif
469 82424832 ths
#if defined(TARGET_NR_openat) && defined(__NR_openat)
470 82424832 ths
_syscall4(int,sys_openat,int,dirfd,const char *,pathname,int,flags,mode_t,mode)
471 82424832 ths
#endif
472 5e0ccb18 ths
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
473 5e0ccb18 ths
_syscall4(int,sys_readlinkat,int,dirfd,const char *,pathname,
474 5e0ccb18 ths
          char *,buf,size_t,bufsize)
475 5e0ccb18 ths
#endif
476 722183f6 ths
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
477 722183f6 ths
_syscall4(int,sys_renameat,int,olddirfd,const char *,oldpath,
478 722183f6 ths
          int,newdirfd,const char *,newpath)
479 722183f6 ths
#endif
480 b51eaa82 ths
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
481 f0b6243d ths
_syscall3(int,sys_symlinkat,const char *,oldpath,
482 f0b6243d ths
          int,newdirfd,const char *,newpath)
483 f0b6243d ths
#endif
484 8170f56b ths
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
485 8170f56b ths
_syscall3(int,sys_unlinkat,int,dirfd,const char *,pathname,int,flags)
486 8170f56b ths
#endif
487 ebc996f3 Riku Voipio
488 ebc996f3 Riku Voipio
#endif /* CONFIG_ATFILE */
489 ebc996f3 Riku Voipio
490 ebc996f3 Riku Voipio
#ifdef CONFIG_UTIMENSAT
491 ebc996f3 Riku Voipio
static int sys_utimensat(int dirfd, const char *pathname,
492 ebc996f3 Riku Voipio
    const struct timespec times[2], int flags)
493 ebc996f3 Riku Voipio
{
494 ebc996f3 Riku Voipio
    if (pathname == NULL)
495 ebc996f3 Riku Voipio
        return futimens(dirfd, times);
496 ebc996f3 Riku Voipio
    else
497 ebc996f3 Riku Voipio
        return utimensat(dirfd, pathname, times, flags);
498 ebc996f3 Riku Voipio
}
499 ebc996f3 Riku Voipio
#else
500 9007f0ef ths
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
501 9007f0ef ths
_syscall4(int,sys_utimensat,int,dirfd,const char *,pathname,
502 9007f0ef ths
          const struct timespec *,tsp,int,flags)
503 9007f0ef ths
#endif
504 ebc996f3 Riku Voipio
#endif /* CONFIG_UTIMENSAT  */
505 3b3f24ad aurel32
506 3b3f24ad aurel32
#ifdef CONFIG_INOTIFY
507 8690e420 aurel32
#include <sys/inotify.h>
508 3b3f24ad aurel32
509 39b59763 aurel32
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
510 3b3f24ad aurel32
static int sys_inotify_init(void)
511 3b3f24ad aurel32
{
512 3b3f24ad aurel32
  return (inotify_init());
513 3b3f24ad aurel32
}
514 39b59763 aurel32
#endif
515 39b59763 aurel32
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
516 3b3f24ad aurel32
static int sys_inotify_add_watch(int fd,const char *pathname, int32_t mask)
517 3b3f24ad aurel32
{
518 3b3f24ad aurel32
  return (inotify_add_watch(fd, pathname, mask));
519 3b3f24ad aurel32
}
520 39b59763 aurel32
#endif
521 39b59763 aurel32
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
522 3b3f24ad aurel32
static int sys_inotify_rm_watch(int fd, int32_t wd)
523 3b3f24ad aurel32
{
524 8690e420 aurel32
  return (inotify_rm_watch(fd, wd));
525 3b3f24ad aurel32
}
526 bd0c5661 pbrook
#endif
527 c05c7a73 Riku Voipio
#ifdef CONFIG_INOTIFY1
528 c05c7a73 Riku Voipio
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
529 c05c7a73 Riku Voipio
static int sys_inotify_init1(int flags)
530 c05c7a73 Riku Voipio
{
531 c05c7a73 Riku Voipio
  return (inotify_init1(flags));
532 c05c7a73 Riku Voipio
}
533 c05c7a73 Riku Voipio
#endif
534 c05c7a73 Riku Voipio
#endif
535 3b3f24ad aurel32
#else
536 3b3f24ad aurel32
/* Userspace can usually survive runtime without inotify */
537 3b3f24ad aurel32
#undef TARGET_NR_inotify_init
538 c05c7a73 Riku Voipio
#undef TARGET_NR_inotify_init1
539 3b3f24ad aurel32
#undef TARGET_NR_inotify_add_watch
540 3b3f24ad aurel32
#undef TARGET_NR_inotify_rm_watch
541 3b3f24ad aurel32
#endif /* CONFIG_INOTIFY  */
542 3b3f24ad aurel32
543 d8035d4c Mike Frysinger
#if defined(TARGET_NR_ppoll)
544 d8035d4c Mike Frysinger
#ifndef __NR_ppoll
545 d8035d4c Mike Frysinger
# define __NR_ppoll -1
546 d8035d4c Mike Frysinger
#endif
547 d8035d4c Mike Frysinger
#define __NR_sys_ppoll __NR_ppoll
548 d8035d4c Mike Frysinger
_syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
549 d8035d4c Mike Frysinger
          struct timespec *, timeout, const __sigset_t *, sigmask,
550 d8035d4c Mike Frysinger
          size_t, sigsetsize)
551 d8035d4c Mike Frysinger
#endif
552 66fb9763 bellard
553 055e0906 Mike Frysinger
#if defined(TARGET_NR_pselect6)
554 055e0906 Mike Frysinger
#ifndef __NR_pselect6
555 055e0906 Mike Frysinger
# define __NR_pselect6 -1
556 055e0906 Mike Frysinger
#endif
557 055e0906 Mike Frysinger
#define __NR_sys_pselect6 __NR_pselect6
558 055e0906 Mike Frysinger
_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
559 055e0906 Mike Frysinger
          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
560 055e0906 Mike Frysinger
#endif
561 055e0906 Mike Frysinger
562 163a05a8 Peter Maydell
#if defined(TARGET_NR_prlimit64)
563 163a05a8 Peter Maydell
#ifndef __NR_prlimit64
564 163a05a8 Peter Maydell
# define __NR_prlimit64 -1
565 163a05a8 Peter Maydell
#endif
566 163a05a8 Peter Maydell
#define __NR_sys_prlimit64 __NR_prlimit64
567 163a05a8 Peter Maydell
/* The glibc rlimit structure may not be that used by the underlying syscall */
568 163a05a8 Peter Maydell
struct host_rlimit64 {
569 163a05a8 Peter Maydell
    uint64_t rlim_cur;
570 163a05a8 Peter Maydell
    uint64_t rlim_max;
571 163a05a8 Peter Maydell
};
572 163a05a8 Peter Maydell
_syscall4(int, sys_prlimit64, pid_t, pid, int, resource,
573 163a05a8 Peter Maydell
          const struct host_rlimit64 *, new_limit,
574 163a05a8 Peter Maydell
          struct host_rlimit64 *, old_limit)
575 163a05a8 Peter Maydell
#endif
576 163a05a8 Peter Maydell
577 66fb9763 bellard
extern int personality(int);
578 9de5e440 bellard
extern int flock(int, int);
579 9de5e440 bellard
extern int setfsuid(int);
580 9de5e440 bellard
extern int setfsgid(int);
581 19b84f3c bellard
extern int setgroups(int, gid_t *);
582 31e31b8a bellard
583 b92c47c1 ths
#define ERRNO_TABLE_SIZE 1200
584 b92c47c1 ths
585 b92c47c1 ths
/* target_to_host_errno_table[] is initialized from
586 b92c47c1 ths
 * host_to_target_errno_table[] in syscall_init(). */
587 b92c47c1 ths
static uint16_t target_to_host_errno_table[ERRNO_TABLE_SIZE] = {
588 b92c47c1 ths
};
589 b92c47c1 ths
590 637947f1 ths
/*
591 fe8f096b ths
 * This list is the union of errno values overridden in asm-<arch>/errno.h
592 637947f1 ths
 * minus the errnos that are not actually generic to all archs.
593 637947f1 ths
 */
594 b92c47c1 ths
static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
595 637947f1 ths
    [EIDRM]                = TARGET_EIDRM,
596 637947f1 ths
    [ECHRNG]                = TARGET_ECHRNG,
597 637947f1 ths
    [EL2NSYNC]                = TARGET_EL2NSYNC,
598 637947f1 ths
    [EL3HLT]                = TARGET_EL3HLT,
599 637947f1 ths
    [EL3RST]                = TARGET_EL3RST,
600 637947f1 ths
    [ELNRNG]                = TARGET_ELNRNG,
601 637947f1 ths
    [EUNATCH]                = TARGET_EUNATCH,
602 637947f1 ths
    [ENOCSI]                = TARGET_ENOCSI,
603 637947f1 ths
    [EL2HLT]                = TARGET_EL2HLT,
604 637947f1 ths
    [EDEADLK]                = TARGET_EDEADLK,
605 637947f1 ths
    [ENOLCK]                = TARGET_ENOLCK,
606 637947f1 ths
    [EBADE]                = TARGET_EBADE,
607 637947f1 ths
    [EBADR]                = TARGET_EBADR,
608 637947f1 ths
    [EXFULL]                = TARGET_EXFULL,
609 637947f1 ths
    [ENOANO]                = TARGET_ENOANO,
610 637947f1 ths
    [EBADRQC]                = TARGET_EBADRQC,
611 637947f1 ths
    [EBADSLT]                = TARGET_EBADSLT,
612 637947f1 ths
    [EBFONT]                = TARGET_EBFONT,
613 637947f1 ths
    [ENOSTR]                = TARGET_ENOSTR,
614 637947f1 ths
    [ENODATA]                = TARGET_ENODATA,
615 637947f1 ths
    [ETIME]                = TARGET_ETIME,
616 637947f1 ths
    [ENOSR]                = TARGET_ENOSR,
617 637947f1 ths
    [ENONET]                = TARGET_ENONET,
618 637947f1 ths
    [ENOPKG]                = TARGET_ENOPKG,
619 637947f1 ths
    [EREMOTE]                = TARGET_EREMOTE,
620 637947f1 ths
    [ENOLINK]                = TARGET_ENOLINK,
621 637947f1 ths
    [EADV]                = TARGET_EADV,
622 637947f1 ths
    [ESRMNT]                = TARGET_ESRMNT,
623 637947f1 ths
    [ECOMM]                = TARGET_ECOMM,
624 637947f1 ths
    [EPROTO]                = TARGET_EPROTO,
625 637947f1 ths
    [EDOTDOT]                = TARGET_EDOTDOT,
626 637947f1 ths
    [EMULTIHOP]                = TARGET_EMULTIHOP,
627 637947f1 ths
    [EBADMSG]                = TARGET_EBADMSG,
628 637947f1 ths
    [ENAMETOOLONG]        = TARGET_ENAMETOOLONG,
629 637947f1 ths
    [EOVERFLOW]                = TARGET_EOVERFLOW,
630 637947f1 ths
    [ENOTUNIQ]                = TARGET_ENOTUNIQ,
631 637947f1 ths
    [EBADFD]                = TARGET_EBADFD,
632 637947f1 ths
    [EREMCHG]                = TARGET_EREMCHG,
633 637947f1 ths
    [ELIBACC]                = TARGET_ELIBACC,
634 637947f1 ths
    [ELIBBAD]                = TARGET_ELIBBAD,
635 637947f1 ths
    [ELIBSCN]                = TARGET_ELIBSCN,
636 637947f1 ths
    [ELIBMAX]                = TARGET_ELIBMAX,
637 637947f1 ths
    [ELIBEXEC]                = TARGET_ELIBEXEC,
638 637947f1 ths
    [EILSEQ]                = TARGET_EILSEQ,
639 637947f1 ths
    [ENOSYS]                = TARGET_ENOSYS,
640 637947f1 ths
    [ELOOP]                = TARGET_ELOOP,
641 637947f1 ths
    [ERESTART]                = TARGET_ERESTART,
642 637947f1 ths
    [ESTRPIPE]                = TARGET_ESTRPIPE,
643 637947f1 ths
    [ENOTEMPTY]                = TARGET_ENOTEMPTY,
644 637947f1 ths
    [EUSERS]                = TARGET_EUSERS,
645 637947f1 ths
    [ENOTSOCK]                = TARGET_ENOTSOCK,
646 637947f1 ths
    [EDESTADDRREQ]        = TARGET_EDESTADDRREQ,
647 637947f1 ths
    [EMSGSIZE]                = TARGET_EMSGSIZE,
648 637947f1 ths
    [EPROTOTYPE]        = TARGET_EPROTOTYPE,
649 637947f1 ths
    [ENOPROTOOPT]        = TARGET_ENOPROTOOPT,
650 637947f1 ths
    [EPROTONOSUPPORT]        = TARGET_EPROTONOSUPPORT,
651 637947f1 ths
    [ESOCKTNOSUPPORT]        = TARGET_ESOCKTNOSUPPORT,
652 637947f1 ths
    [EOPNOTSUPP]        = TARGET_EOPNOTSUPP,
653 637947f1 ths
    [EPFNOSUPPORT]        = TARGET_EPFNOSUPPORT,
654 637947f1 ths
    [EAFNOSUPPORT]        = TARGET_EAFNOSUPPORT,
655 637947f1 ths
    [EADDRINUSE]        = TARGET_EADDRINUSE,
656 637947f1 ths
    [EADDRNOTAVAIL]        = TARGET_EADDRNOTAVAIL,
657 637947f1 ths
    [ENETDOWN]                = TARGET_ENETDOWN,
658 637947f1 ths
    [ENETUNREACH]        = TARGET_ENETUNREACH,
659 637947f1 ths
    [ENETRESET]                = TARGET_ENETRESET,
660 637947f1 ths
    [ECONNABORTED]        = TARGET_ECONNABORTED,
661 637947f1 ths
    [ECONNRESET]        = TARGET_ECONNRESET,
662 637947f1 ths
    [ENOBUFS]                = TARGET_ENOBUFS,
663 637947f1 ths
    [EISCONN]                = TARGET_EISCONN,
664 637947f1 ths
    [ENOTCONN]                = TARGET_ENOTCONN,
665 637947f1 ths
    [EUCLEAN]                = TARGET_EUCLEAN,
666 637947f1 ths
    [ENOTNAM]                = TARGET_ENOTNAM,
667 637947f1 ths
    [ENAVAIL]                = TARGET_ENAVAIL,
668 637947f1 ths
    [EISNAM]                = TARGET_EISNAM,
669 637947f1 ths
    [EREMOTEIO]                = TARGET_EREMOTEIO,
670 637947f1 ths
    [ESHUTDOWN]                = TARGET_ESHUTDOWN,
671 637947f1 ths
    [ETOOMANYREFS]        = TARGET_ETOOMANYREFS,
672 637947f1 ths
    [ETIMEDOUT]                = TARGET_ETIMEDOUT,
673 637947f1 ths
    [ECONNREFUSED]        = TARGET_ECONNREFUSED,
674 637947f1 ths
    [EHOSTDOWN]                = TARGET_EHOSTDOWN,
675 637947f1 ths
    [EHOSTUNREACH]        = TARGET_EHOSTUNREACH,
676 637947f1 ths
    [EALREADY]                = TARGET_EALREADY,
677 637947f1 ths
    [EINPROGRESS]        = TARGET_EINPROGRESS,
678 637947f1 ths
    [ESTALE]                = TARGET_ESTALE,
679 637947f1 ths
    [ECANCELED]                = TARGET_ECANCELED,
680 637947f1 ths
    [ENOMEDIUM]                = TARGET_ENOMEDIUM,
681 637947f1 ths
    [EMEDIUMTYPE]        = TARGET_EMEDIUMTYPE,
682 b7fe5db7 ths
#ifdef ENOKEY
683 637947f1 ths
    [ENOKEY]                = TARGET_ENOKEY,
684 b7fe5db7 ths
#endif
685 b7fe5db7 ths
#ifdef EKEYEXPIRED
686 637947f1 ths
    [EKEYEXPIRED]        = TARGET_EKEYEXPIRED,
687 b7fe5db7 ths
#endif
688 b7fe5db7 ths
#ifdef EKEYREVOKED
689 637947f1 ths
    [EKEYREVOKED]        = TARGET_EKEYREVOKED,
690 b7fe5db7 ths
#endif
691 b7fe5db7 ths
#ifdef EKEYREJECTED
692 637947f1 ths
    [EKEYREJECTED]        = TARGET_EKEYREJECTED,
693 b7fe5db7 ths
#endif
694 b7fe5db7 ths
#ifdef EOWNERDEAD
695 637947f1 ths
    [EOWNERDEAD]        = TARGET_EOWNERDEAD,
696 b7fe5db7 ths
#endif
697 b7fe5db7 ths
#ifdef ENOTRECOVERABLE
698 637947f1 ths
    [ENOTRECOVERABLE]        = TARGET_ENOTRECOVERABLE,
699 b7fe5db7 ths
#endif
700 b92c47c1 ths
};
701 637947f1 ths
702 637947f1 ths
static inline int host_to_target_errno(int err)
703 637947f1 ths
{
704 637947f1 ths
    if(host_to_target_errno_table[err])
705 637947f1 ths
        return host_to_target_errno_table[err];
706 637947f1 ths
    return err;
707 637947f1 ths
}
708 637947f1 ths
709 b92c47c1 ths
static inline int target_to_host_errno(int err)
710 b92c47c1 ths
{
711 b92c47c1 ths
    if (target_to_host_errno_table[err])
712 b92c47c1 ths
        return target_to_host_errno_table[err];
713 b92c47c1 ths
    return err;
714 b92c47c1 ths
}
715 b92c47c1 ths
716 992f48a0 blueswir1
static inline abi_long get_errno(abi_long ret)
717 31e31b8a bellard
{
718 31e31b8a bellard
    if (ret == -1)
719 637947f1 ths
        return -host_to_target_errno(errno);
720 31e31b8a bellard
    else
721 31e31b8a bellard
        return ret;
722 31e31b8a bellard
}
723 31e31b8a bellard
724 992f48a0 blueswir1
static inline int is_error(abi_long ret)
725 31e31b8a bellard
{
726 992f48a0 blueswir1
    return (abi_ulong)ret >= (abi_ulong)(-4096);
727 31e31b8a bellard
}
728 31e31b8a bellard
729 b92c47c1 ths
char *target_strerror(int err)
730 b92c47c1 ths
{
731 b92c47c1 ths
    return strerror(target_to_host_errno(err));
732 b92c47c1 ths
}
733 b92c47c1 ths
734 992f48a0 blueswir1
static abi_ulong target_brk;
735 992f48a0 blueswir1
static abi_ulong target_original_brk;
736 4d1de87c vincent
static abi_ulong brk_page;
737 31e31b8a bellard
738 992f48a0 blueswir1
void target_set_brk(abi_ulong new_brk)
739 31e31b8a bellard
{
740 4c1de73d blueswir1
    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
741 4d1de87c vincent
    brk_page = HOST_PAGE_ALIGN(target_brk);
742 31e31b8a bellard
}
743 31e31b8a bellard
744 4d1de87c vincent
//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
745 4d1de87c vincent
#define DEBUGF_BRK(message, args...)
746 4d1de87c vincent
747 0da46a6e ths
/* do_brk() must return target values and target errnos. */
748 992f48a0 blueswir1
abi_long do_brk(abi_ulong new_brk)
749 31e31b8a bellard
{
750 992f48a0 blueswir1
    abi_long mapped_addr;
751 31e31b8a bellard
    int        new_alloc_size;
752 31e31b8a bellard
753 4d1de87c vincent
    DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
754 4d1de87c vincent
755 4d1de87c vincent
    if (!new_brk) {
756 4d1de87c vincent
        DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
757 53a5960a pbrook
        return target_brk;
758 4d1de87c vincent
    }
759 4d1de87c vincent
    if (new_brk < target_original_brk) {
760 4d1de87c vincent
        DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
761 7ab240ad balrog
        return target_brk;
762 4d1de87c vincent
    }
763 3b46e624 ths
764 4d1de87c vincent
    /* If the new brk is less than the highest page reserved to the
765 4d1de87c vincent
     * target heap allocation, set it and we're almost done...  */
766 4d1de87c vincent
    if (new_brk <= brk_page) {
767 4d1de87c vincent
        /* Heap contents are initialized to zero, as for anonymous
768 4d1de87c vincent
         * mapped pages.  */
769 4d1de87c vincent
        if (new_brk > target_brk) {
770 4d1de87c vincent
            memset(g2h(target_brk), 0, new_brk - target_brk);
771 4d1de87c vincent
        }
772 31e31b8a bellard
        target_brk = new_brk;
773 4d1de87c vincent
        DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk);
774 53a5960a pbrook
            return target_brk;
775 31e31b8a bellard
    }
776 31e31b8a bellard
777 00faf08c Peter Maydell
    /* We need to allocate more memory after the brk... Note that
778 00faf08c Peter Maydell
     * we don't use MAP_FIXED because that will map over the top of
779 00faf08c Peter Maydell
     * any existing mapping (like the one with the host libc or qemu
780 00faf08c Peter Maydell
     * itself); instead we treat "mapped but at wrong address" as
781 00faf08c Peter Maydell
     * a failure and unmap again.
782 00faf08c Peter Maydell
     */
783 4d1de87c vincent
    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
784 5fafdf24 ths
    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
785 54936004 bellard
                                        PROT_READ|PROT_WRITE,
786 00faf08c Peter Maydell
                                        MAP_ANON|MAP_PRIVATE, 0, 0));
787 00faf08c Peter Maydell
788 00faf08c Peter Maydell
    if (mapped_addr == brk_page) {
789 00faf08c Peter Maydell
        target_brk = new_brk;
790 4d1de87c vincent
        brk_page = HOST_PAGE_ALIGN(target_brk);
791 4d1de87c vincent
        DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
792 00faf08c Peter Maydell
        return target_brk;
793 00faf08c Peter Maydell
    } else if (mapped_addr != -1) {
794 00faf08c Peter Maydell
        /* Mapped but at wrong address, meaning there wasn't actually
795 00faf08c Peter Maydell
         * enough space for this brk.
796 00faf08c Peter Maydell
         */
797 00faf08c Peter Maydell
        target_munmap(mapped_addr, new_alloc_size);
798 00faf08c Peter Maydell
        mapped_addr = -1;
799 4d1de87c vincent
        DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
800 4d1de87c vincent
    }
801 4d1de87c vincent
    else {
802 4d1de87c vincent
        DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
803 00faf08c Peter Maydell
    }
804 7ab240ad balrog
805 7dd46c02 Richard Henderson
#if defined(TARGET_ALPHA)
806 7dd46c02 Richard Henderson
    /* We (partially) emulate OSF/1 on Alpha, which requires we
807 7dd46c02 Richard Henderson
       return a proper errno, not an unchanged brk value.  */
808 00faf08c Peter Maydell
    return -TARGET_ENOMEM;
809 7dd46c02 Richard Henderson
#endif
810 00faf08c Peter Maydell
    /* For everything else, return the previous break. */
811 7ab240ad balrog
    return target_brk;
812 31e31b8a bellard
}
813 31e31b8a bellard
814 26edcf41 ths
static inline abi_long copy_from_user_fdset(fd_set *fds,
815 26edcf41 ths
                                            abi_ulong target_fds_addr,
816 26edcf41 ths
                                            int n)
817 31e31b8a bellard
{
818 26edcf41 ths
    int i, nw, j, k;
819 26edcf41 ths
    abi_ulong b, *target_fds;
820 26edcf41 ths
821 26edcf41 ths
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
822 26edcf41 ths
    if (!(target_fds = lock_user(VERIFY_READ,
823 26edcf41 ths
                                 target_fds_addr,
824 26edcf41 ths
                                 sizeof(abi_ulong) * nw,
825 26edcf41 ths
                                 1)))
826 26edcf41 ths
        return -TARGET_EFAULT;
827 26edcf41 ths
828 26edcf41 ths
    FD_ZERO(fds);
829 26edcf41 ths
    k = 0;
830 26edcf41 ths
    for (i = 0; i < nw; i++) {
831 26edcf41 ths
        /* grab the abi_ulong */
832 26edcf41 ths
        __get_user(b, &target_fds[i]);
833 26edcf41 ths
        for (j = 0; j < TARGET_ABI_BITS; j++) {
834 26edcf41 ths
            /* check the bit inside the abi_ulong */
835 26edcf41 ths
            if ((b >> j) & 1)
836 26edcf41 ths
                FD_SET(k, fds);
837 26edcf41 ths
            k++;
838 31e31b8a bellard
        }
839 31e31b8a bellard
    }
840 26edcf41 ths
841 26edcf41 ths
    unlock_user(target_fds, target_fds_addr, 0);
842 26edcf41 ths
843 26edcf41 ths
    return 0;
844 31e31b8a bellard
}
845 31e31b8a bellard
846 055e0906 Mike Frysinger
static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
847 055e0906 Mike Frysinger
                                                 abi_ulong target_fds_addr,
848 055e0906 Mike Frysinger
                                                 int n)
849 055e0906 Mike Frysinger
{
850 055e0906 Mike Frysinger
    if (target_fds_addr) {
851 055e0906 Mike Frysinger
        if (copy_from_user_fdset(fds, target_fds_addr, n))
852 055e0906 Mike Frysinger
            return -TARGET_EFAULT;
853 055e0906 Mike Frysinger
        *fds_ptr = fds;
854 055e0906 Mike Frysinger
    } else {
855 055e0906 Mike Frysinger
        *fds_ptr = NULL;
856 055e0906 Mike Frysinger
    }
857 055e0906 Mike Frysinger
    return 0;
858 055e0906 Mike Frysinger
}
859 055e0906 Mike Frysinger
860 26edcf41 ths
static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
861 26edcf41 ths
                                          const fd_set *fds,
862 26edcf41 ths
                                          int n)
863 31e31b8a bellard
{
864 31e31b8a bellard
    int i, nw, j, k;
865 992f48a0 blueswir1
    abi_long v;
866 26edcf41 ths
    abi_ulong *target_fds;
867 31e31b8a bellard
868 26edcf41 ths
    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
869 26edcf41 ths
    if (!(target_fds = lock_user(VERIFY_WRITE,
870 26edcf41 ths
                                 target_fds_addr,
871 26edcf41 ths
                                 sizeof(abi_ulong) * nw,
872 26edcf41 ths
                                 0)))
873 26edcf41 ths
        return -TARGET_EFAULT;
874 26edcf41 ths
875 26edcf41 ths
    k = 0;
876 26edcf41 ths
    for (i = 0; i < nw; i++) {
877 26edcf41 ths
        v = 0;
878 26edcf41 ths
        for (j = 0; j < TARGET_ABI_BITS; j++) {
879 26edcf41 ths
            v |= ((FD_ISSET(k, fds) != 0) << j);
880 26edcf41 ths
            k++;
881 31e31b8a bellard
        }
882 26edcf41 ths
        __put_user(v, &target_fds[i]);
883 31e31b8a bellard
    }
884 26edcf41 ths
885 26edcf41 ths
    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
886 26edcf41 ths
887 26edcf41 ths
    return 0;
888 31e31b8a bellard
}
889 31e31b8a bellard
890 c596ed17 bellard
#if defined(__alpha__)
891 c596ed17 bellard
#define HOST_HZ 1024
892 c596ed17 bellard
#else
893 c596ed17 bellard
#define HOST_HZ 100
894 c596ed17 bellard
#endif
895 c596ed17 bellard
896 992f48a0 blueswir1
static inline abi_long host_to_target_clock_t(long ticks)
897 c596ed17 bellard
{
898 c596ed17 bellard
#if HOST_HZ == TARGET_HZ
899 c596ed17 bellard
    return ticks;
900 c596ed17 bellard
#else
901 c596ed17 bellard
    return ((int64_t)ticks * TARGET_HZ) / HOST_HZ;
902 c596ed17 bellard
#endif
903 c596ed17 bellard
}
904 c596ed17 bellard
905 579a97f7 bellard
static inline abi_long host_to_target_rusage(abi_ulong target_addr,
906 579a97f7 bellard
                                             const struct rusage *rusage)
907 b409186b bellard
{
908 53a5960a pbrook
    struct target_rusage *target_rusage;
909 53a5960a pbrook
910 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0))
911 579a97f7 bellard
        return -TARGET_EFAULT;
912 b409186b bellard
    target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
913 b409186b bellard
    target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
914 b409186b bellard
    target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
915 b409186b bellard
    target_rusage->ru_stime.tv_usec = tswapl(rusage->ru_stime.tv_usec);
916 b409186b bellard
    target_rusage->ru_maxrss = tswapl(rusage->ru_maxrss);
917 b409186b bellard
    target_rusage->ru_ixrss = tswapl(rusage->ru_ixrss);
918 b409186b bellard
    target_rusage->ru_idrss = tswapl(rusage->ru_idrss);
919 b409186b bellard
    target_rusage->ru_isrss = tswapl(rusage->ru_isrss);
920 b409186b bellard
    target_rusage->ru_minflt = tswapl(rusage->ru_minflt);
921 b409186b bellard
    target_rusage->ru_majflt = tswapl(rusage->ru_majflt);
922 b409186b bellard
    target_rusage->ru_nswap = tswapl(rusage->ru_nswap);
923 b409186b bellard
    target_rusage->ru_inblock = tswapl(rusage->ru_inblock);
924 b409186b bellard
    target_rusage->ru_oublock = tswapl(rusage->ru_oublock);
925 b409186b bellard
    target_rusage->ru_msgsnd = tswapl(rusage->ru_msgsnd);
926 b409186b bellard
    target_rusage->ru_msgrcv = tswapl(rusage->ru_msgrcv);
927 b409186b bellard
    target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
928 b409186b bellard
    target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
929 b409186b bellard
    target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
930 53a5960a pbrook
    unlock_user_struct(target_rusage, target_addr, 1);
931 579a97f7 bellard
932 579a97f7 bellard
    return 0;
933 b409186b bellard
}
934 b409186b bellard
935 81bbe906 takasi-y@ops.dti.ne.jp
static inline rlim_t target_to_host_rlim(target_ulong target_rlim)
936 81bbe906 takasi-y@ops.dti.ne.jp
{
937 95b33b2f Wesley W. Terpstra
    target_ulong target_rlim_swap;
938 95b33b2f Wesley W. Terpstra
    rlim_t result;
939 95b33b2f Wesley W. Terpstra
    
940 95b33b2f Wesley W. Terpstra
    target_rlim_swap = tswapl(target_rlim);
941 95b33b2f Wesley W. Terpstra
    if (target_rlim_swap == TARGET_RLIM_INFINITY || target_rlim_swap != (rlim_t)target_rlim_swap)
942 95b33b2f Wesley W. Terpstra
        result = RLIM_INFINITY;
943 81bbe906 takasi-y@ops.dti.ne.jp
    else
944 95b33b2f Wesley W. Terpstra
        result = target_rlim_swap;
945 95b33b2f Wesley W. Terpstra
    
946 95b33b2f Wesley W. Terpstra
    return result;
947 81bbe906 takasi-y@ops.dti.ne.jp
}
948 81bbe906 takasi-y@ops.dti.ne.jp
949 81bbe906 takasi-y@ops.dti.ne.jp
static inline target_ulong host_to_target_rlim(rlim_t rlim)
950 81bbe906 takasi-y@ops.dti.ne.jp
{
951 95b33b2f Wesley W. Terpstra
    target_ulong target_rlim_swap;
952 95b33b2f Wesley W. Terpstra
    target_ulong result;
953 95b33b2f Wesley W. Terpstra
    
954 81bbe906 takasi-y@ops.dti.ne.jp
    if (rlim == RLIM_INFINITY || rlim != (target_long)rlim)
955 95b33b2f Wesley W. Terpstra
        target_rlim_swap = TARGET_RLIM_INFINITY;
956 81bbe906 takasi-y@ops.dti.ne.jp
    else
957 95b33b2f Wesley W. Terpstra
        target_rlim_swap = rlim;
958 95b33b2f Wesley W. Terpstra
    result = tswapl(target_rlim_swap);
959 95b33b2f Wesley W. Terpstra
    
960 95b33b2f Wesley W. Terpstra
    return result;
961 81bbe906 takasi-y@ops.dti.ne.jp
}
962 81bbe906 takasi-y@ops.dti.ne.jp
963 788f5ec4 ths
static inline abi_long copy_from_user_timeval(struct timeval *tv,
964 788f5ec4 ths
                                              abi_ulong target_tv_addr)
965 31e31b8a bellard
{
966 53a5960a pbrook
    struct target_timeval *target_tv;
967 53a5960a pbrook
968 788f5ec4 ths
    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 1))
969 579a97f7 bellard
        return -TARGET_EFAULT;
970 788f5ec4 ths
971 788f5ec4 ths
    __get_user(tv->tv_sec, &target_tv->tv_sec);
972 788f5ec4 ths
    __get_user(tv->tv_usec, &target_tv->tv_usec);
973 788f5ec4 ths
974 788f5ec4 ths
    unlock_user_struct(target_tv, target_tv_addr, 0);
975 579a97f7 bellard
976 579a97f7 bellard
    return 0;
977 31e31b8a bellard
}
978 31e31b8a bellard
979 788f5ec4 ths
static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
980 788f5ec4 ths
                                            const struct timeval *tv)
981 31e31b8a bellard
{
982 53a5960a pbrook
    struct target_timeval *target_tv;
983 53a5960a pbrook
984 788f5ec4 ths
    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0))
985 579a97f7 bellard
        return -TARGET_EFAULT;
986 788f5ec4 ths
987 788f5ec4 ths
    __put_user(tv->tv_sec, &target_tv->tv_sec);
988 788f5ec4 ths
    __put_user(tv->tv_usec, &target_tv->tv_usec);
989 788f5ec4 ths
990 788f5ec4 ths
    unlock_user_struct(target_tv, target_tv_addr, 1);
991 579a97f7 bellard
992 579a97f7 bellard
    return 0;
993 31e31b8a bellard
}
994 31e31b8a bellard
995 8ec9cf89 Nathan Froyd
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
996 8ec9cf89 Nathan Froyd
#include <mqueue.h>
997 8ec9cf89 Nathan Froyd
998 24e1003a aurel32
static inline abi_long copy_from_user_mq_attr(struct mq_attr *attr,
999 24e1003a aurel32
                                              abi_ulong target_mq_attr_addr)
1000 24e1003a aurel32
{
1001 24e1003a aurel32
    struct target_mq_attr *target_mq_attr;
1002 24e1003a aurel32
1003 24e1003a aurel32
    if (!lock_user_struct(VERIFY_READ, target_mq_attr,
1004 24e1003a aurel32
                          target_mq_attr_addr, 1))
1005 24e1003a aurel32
        return -TARGET_EFAULT;
1006 24e1003a aurel32
1007 24e1003a aurel32
    __get_user(attr->mq_flags, &target_mq_attr->mq_flags);
1008 24e1003a aurel32
    __get_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1009 24e1003a aurel32
    __get_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1010 24e1003a aurel32
    __get_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1011 24e1003a aurel32
1012 24e1003a aurel32
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 0);
1013 24e1003a aurel32
1014 24e1003a aurel32
    return 0;
1015 24e1003a aurel32
}
1016 24e1003a aurel32
1017 24e1003a aurel32
static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
1018 24e1003a aurel32
                                            const struct mq_attr *attr)
1019 24e1003a aurel32
{
1020 24e1003a aurel32
    struct target_mq_attr *target_mq_attr;
1021 24e1003a aurel32
1022 24e1003a aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_mq_attr,
1023 24e1003a aurel32
                          target_mq_attr_addr, 0))
1024 24e1003a aurel32
        return -TARGET_EFAULT;
1025 24e1003a aurel32
1026 24e1003a aurel32
    __put_user(attr->mq_flags, &target_mq_attr->mq_flags);
1027 24e1003a aurel32
    __put_user(attr->mq_maxmsg, &target_mq_attr->mq_maxmsg);
1028 24e1003a aurel32
    __put_user(attr->mq_msgsize, &target_mq_attr->mq_msgsize);
1029 24e1003a aurel32
    __put_user(attr->mq_curmsgs, &target_mq_attr->mq_curmsgs);
1030 24e1003a aurel32
1031 24e1003a aurel32
    unlock_user_struct(target_mq_attr, target_mq_attr_addr, 1);
1032 24e1003a aurel32
1033 24e1003a aurel32
    return 0;
1034 24e1003a aurel32
}
1035 8ec9cf89 Nathan Froyd
#endif
1036 31e31b8a bellard
1037 055e0906 Mike Frysinger
#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
1038 0da46a6e ths
/* do_select() must return target values and target errnos. */
1039 992f48a0 blueswir1
static abi_long do_select(int n,
1040 26edcf41 ths
                          abi_ulong rfd_addr, abi_ulong wfd_addr,
1041 26edcf41 ths
                          abi_ulong efd_addr, abi_ulong target_tv_addr)
1042 31e31b8a bellard
{
1043 31e31b8a bellard
    fd_set rfds, wfds, efds;
1044 31e31b8a bellard
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
1045 31e31b8a bellard
    struct timeval tv, *tv_ptr;
1046 992f48a0 blueswir1
    abi_long ret;
1047 31e31b8a bellard
1048 055e0906 Mike Frysinger
    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
1049 055e0906 Mike Frysinger
    if (ret) {
1050 055e0906 Mike Frysinger
        return ret;
1051 53a5960a pbrook
    }
1052 055e0906 Mike Frysinger
    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
1053 055e0906 Mike Frysinger
    if (ret) {
1054 055e0906 Mike Frysinger
        return ret;
1055 53a5960a pbrook
    }
1056 055e0906 Mike Frysinger
    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
1057 055e0906 Mike Frysinger
    if (ret) {
1058 055e0906 Mike Frysinger
        return ret;
1059 53a5960a pbrook
    }
1060 3b46e624 ths
1061 26edcf41 ths
    if (target_tv_addr) {
1062 788f5ec4 ths
        if (copy_from_user_timeval(&tv, target_tv_addr))
1063 788f5ec4 ths
            return -TARGET_EFAULT;
1064 31e31b8a bellard
        tv_ptr = &tv;
1065 31e31b8a bellard
    } else {
1066 31e31b8a bellard
        tv_ptr = NULL;
1067 31e31b8a bellard
    }
1068 26edcf41 ths
1069 31e31b8a bellard
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
1070 53a5960a pbrook
1071 26edcf41 ths
    if (!is_error(ret)) {
1072 26edcf41 ths
        if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
1073 26edcf41 ths
            return -TARGET_EFAULT;
1074 26edcf41 ths
        if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
1075 26edcf41 ths
            return -TARGET_EFAULT;
1076 26edcf41 ths
        if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
1077 26edcf41 ths
            return -TARGET_EFAULT;
1078 31e31b8a bellard
1079 788f5ec4 ths
        if (target_tv_addr && copy_to_user_timeval(target_tv_addr, &tv))
1080 788f5ec4 ths
            return -TARGET_EFAULT;
1081 31e31b8a bellard
    }
1082 579a97f7 bellard
1083 31e31b8a bellard
    return ret;
1084 31e31b8a bellard
}
1085 055e0906 Mike Frysinger
#endif
1086 31e31b8a bellard
1087 099d6b0f Riku Voipio
static abi_long do_pipe2(int host_pipe[], int flags)
1088 099d6b0f Riku Voipio
{
1089 099d6b0f Riku Voipio
#ifdef CONFIG_PIPE2
1090 099d6b0f Riku Voipio
    return pipe2(host_pipe, flags);
1091 099d6b0f Riku Voipio
#else
1092 099d6b0f Riku Voipio
    return -ENOSYS;
1093 099d6b0f Riku Voipio
#endif
1094 099d6b0f Riku Voipio
}
1095 099d6b0f Riku Voipio
1096 fb41a66e Richard Henderson
static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
1097 fb41a66e Richard Henderson
                        int flags, int is_pipe2)
1098 099d6b0f Riku Voipio
{
1099 099d6b0f Riku Voipio
    int host_pipe[2];
1100 099d6b0f Riku Voipio
    abi_long ret;
1101 099d6b0f Riku Voipio
    ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe);
1102 099d6b0f Riku Voipio
1103 099d6b0f Riku Voipio
    if (is_error(ret))
1104 099d6b0f Riku Voipio
        return get_errno(ret);
1105 fb41a66e Richard Henderson
1106 fb41a66e Richard Henderson
    /* Several targets have special calling conventions for the original
1107 fb41a66e Richard Henderson
       pipe syscall, but didn't replicate this into the pipe2 syscall.  */
1108 fb41a66e Richard Henderson
    if (!is_pipe2) {
1109 fb41a66e Richard Henderson
#if defined(TARGET_ALPHA)
1110 fb41a66e Richard Henderson
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = host_pipe[1];
1111 fb41a66e Richard Henderson
        return host_pipe[0];
1112 fb41a66e Richard Henderson
#elif defined(TARGET_MIPS)
1113 fb41a66e Richard Henderson
        ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
1114 fb41a66e Richard Henderson
        return host_pipe[0];
1115 fb41a66e Richard Henderson
#elif defined(TARGET_SH4)
1116 597c0212 takasi-y@ops.dti.ne.jp
        ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
1117 fb41a66e Richard Henderson
        return host_pipe[0];
1118 597c0212 takasi-y@ops.dti.ne.jp
#endif
1119 fb41a66e Richard Henderson
    }
1120 fb41a66e Richard Henderson
1121 099d6b0f Riku Voipio
    if (put_user_s32(host_pipe[0], pipedes)
1122 099d6b0f Riku Voipio
        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
1123 099d6b0f Riku Voipio
        return -TARGET_EFAULT;
1124 099d6b0f Riku Voipio
    return get_errno(ret);
1125 099d6b0f Riku Voipio
}
1126 099d6b0f Riku Voipio
1127 b975b83b Lionel Landwerlin
static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
1128 b975b83b Lionel Landwerlin
                                              abi_ulong target_addr,
1129 b975b83b Lionel Landwerlin
                                              socklen_t len)
1130 b975b83b Lionel Landwerlin
{
1131 b975b83b Lionel Landwerlin
    struct target_ip_mreqn *target_smreqn;
1132 b975b83b Lionel Landwerlin
1133 b975b83b Lionel Landwerlin
    target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1);
1134 b975b83b Lionel Landwerlin
    if (!target_smreqn)
1135 b975b83b Lionel Landwerlin
        return -TARGET_EFAULT;
1136 b975b83b Lionel Landwerlin
    mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr;
1137 b975b83b Lionel Landwerlin
    mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr;
1138 b975b83b Lionel Landwerlin
    if (len == sizeof(struct target_ip_mreqn))
1139 b975b83b Lionel Landwerlin
        mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex);
1140 b975b83b Lionel Landwerlin
    unlock_user(target_smreqn, target_addr, 0);
1141 b975b83b Lionel Landwerlin
1142 b975b83b Lionel Landwerlin
    return 0;
1143 b975b83b Lionel Landwerlin
}
1144 b975b83b Lionel Landwerlin
1145 579a97f7 bellard
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
1146 579a97f7 bellard
                                               abi_ulong target_addr,
1147 579a97f7 bellard
                                               socklen_t len)
1148 7854b056 bellard
{
1149 607175e0 aurel32
    const socklen_t unix_maxlen = sizeof (struct sockaddr_un);
1150 607175e0 aurel32
    sa_family_t sa_family;
1151 53a5960a pbrook
    struct target_sockaddr *target_saddr;
1152 53a5960a pbrook
1153 579a97f7 bellard
    target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
1154 579a97f7 bellard
    if (!target_saddr)
1155 579a97f7 bellard
        return -TARGET_EFAULT;
1156 607175e0 aurel32
1157 607175e0 aurel32
    sa_family = tswap16(target_saddr->sa_family);
1158 607175e0 aurel32
1159 607175e0 aurel32
    /* Oops. The caller might send a incomplete sun_path; sun_path
1160 607175e0 aurel32
     * must be terminated by \0 (see the manual page), but
1161 607175e0 aurel32
     * unfortunately it is quite common to specify sockaddr_un
1162 607175e0 aurel32
     * length as "strlen(x->sun_path)" while it should be
1163 607175e0 aurel32
     * "strlen(...) + 1". We'll fix that here if needed.
1164 607175e0 aurel32
     * Linux kernel has a similar feature.
1165 607175e0 aurel32
     */
1166 607175e0 aurel32
1167 607175e0 aurel32
    if (sa_family == AF_UNIX) {
1168 607175e0 aurel32
        if (len < unix_maxlen && len > 0) {
1169 607175e0 aurel32
            char *cp = (char*)target_saddr;
1170 607175e0 aurel32
1171 607175e0 aurel32
            if ( cp[len-1] && !cp[len] )
1172 607175e0 aurel32
                len++;
1173 607175e0 aurel32
        }
1174 607175e0 aurel32
        if (len > unix_maxlen)
1175 607175e0 aurel32
            len = unix_maxlen;
1176 607175e0 aurel32
    }
1177 607175e0 aurel32
1178 53a5960a pbrook
    memcpy(addr, target_saddr, len);
1179 607175e0 aurel32
    addr->sa_family = sa_family;
1180 53a5960a pbrook
    unlock_user(target_saddr, target_addr, 0);
1181 579a97f7 bellard
1182 579a97f7 bellard
    return 0;
1183 7854b056 bellard
}
1184 7854b056 bellard
1185 579a97f7 bellard
static inline abi_long host_to_target_sockaddr(abi_ulong target_addr,
1186 579a97f7 bellard
                                               struct sockaddr *addr,
1187 579a97f7 bellard
                                               socklen_t len)
1188 7854b056 bellard
{
1189 53a5960a pbrook
    struct target_sockaddr *target_saddr;
1190 53a5960a pbrook
1191 579a97f7 bellard
    target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0);
1192 579a97f7 bellard
    if (!target_saddr)
1193 579a97f7 bellard
        return -TARGET_EFAULT;
1194 53a5960a pbrook
    memcpy(target_saddr, addr, len);
1195 53a5960a pbrook
    target_saddr->sa_family = tswap16(addr->sa_family);
1196 53a5960a pbrook
    unlock_user(target_saddr, target_addr, len);
1197 579a97f7 bellard
1198 579a97f7 bellard
    return 0;
1199 7854b056 bellard
}
1200 7854b056 bellard
1201 53a5960a pbrook
/* ??? Should this also swap msgh->name?  */
1202 5a4a898d bellard
static inline abi_long target_to_host_cmsg(struct msghdr *msgh,
1203 5a4a898d bellard
                                           struct target_msghdr *target_msgh)
1204 7854b056 bellard
{
1205 7854b056 bellard
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1206 5a4a898d bellard
    abi_long msg_controllen;
1207 5a4a898d bellard
    abi_ulong target_cmsg_addr;
1208 5a4a898d bellard
    struct target_cmsghdr *target_cmsg;
1209 7854b056 bellard
    socklen_t space = 0;
1210 5a4a898d bellard
    
1211 5a4a898d bellard
    msg_controllen = tswapl(target_msgh->msg_controllen);
1212 5a4a898d bellard
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1213 5a4a898d bellard
        goto the_end;
1214 5a4a898d bellard
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1215 5a4a898d bellard
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1216 5a4a898d bellard
    if (!target_cmsg)
1217 5a4a898d bellard
        return -TARGET_EFAULT;
1218 7854b056 bellard
1219 7854b056 bellard
    while (cmsg && target_cmsg) {
1220 7854b056 bellard
        void *data = CMSG_DATA(cmsg);
1221 7854b056 bellard
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1222 7854b056 bellard
1223 5fafdf24 ths
        int len = tswapl(target_cmsg->cmsg_len)
1224 7854b056 bellard
                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));
1225 7854b056 bellard
1226 7854b056 bellard
        space += CMSG_SPACE(len);
1227 7854b056 bellard
        if (space > msgh->msg_controllen) {
1228 7854b056 bellard
            space -= CMSG_SPACE(len);
1229 31febb71 bellard
            gemu_log("Host cmsg overflow\n");
1230 7854b056 bellard
            break;
1231 7854b056 bellard
        }
1232 7854b056 bellard
1233 7854b056 bellard
        cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);
1234 7854b056 bellard
        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);
1235 7854b056 bellard
        cmsg->cmsg_len = CMSG_LEN(len);
1236 7854b056 bellard
1237 3532fa74 bellard
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1238 7854b056 bellard
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1239 7854b056 bellard
            memcpy(data, target_data, len);
1240 7854b056 bellard
        } else {
1241 7854b056 bellard
            int *fd = (int *)data;
1242 7854b056 bellard
            int *target_fd = (int *)target_data;
1243 7854b056 bellard
            int i, numfds = len / sizeof(int);
1244 7854b056 bellard
1245 7854b056 bellard
            for (i = 0; i < numfds; i++)
1246 7854b056 bellard
                fd[i] = tswap32(target_fd[i]);
1247 7854b056 bellard
        }
1248 7854b056 bellard
1249 7854b056 bellard
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1250 7854b056 bellard
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1251 7854b056 bellard
    }
1252 5a4a898d bellard
    unlock_user(target_cmsg, target_cmsg_addr, 0);
1253 5a4a898d bellard
 the_end:
1254 7854b056 bellard
    msgh->msg_controllen = space;
1255 5a4a898d bellard
    return 0;
1256 7854b056 bellard
}
1257 7854b056 bellard
1258 53a5960a pbrook
/* ??? Should this also swap msgh->name?  */
1259 5a4a898d bellard
static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
1260 5a4a898d bellard
                                           struct msghdr *msgh)
1261 7854b056 bellard
{
1262 7854b056 bellard
    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);
1263 5a4a898d bellard
    abi_long msg_controllen;
1264 5a4a898d bellard
    abi_ulong target_cmsg_addr;
1265 5a4a898d bellard
    struct target_cmsghdr *target_cmsg;
1266 7854b056 bellard
    socklen_t space = 0;
1267 7854b056 bellard
1268 5a4a898d bellard
    msg_controllen = tswapl(target_msgh->msg_controllen);
1269 5a4a898d bellard
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1270 5a4a898d bellard
        goto the_end;
1271 5a4a898d bellard
    target_cmsg_addr = tswapl(target_msgh->msg_control);
1272 5a4a898d bellard
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1273 5a4a898d bellard
    if (!target_cmsg)
1274 5a4a898d bellard
        return -TARGET_EFAULT;
1275 5a4a898d bellard
1276 7854b056 bellard
    while (cmsg && target_cmsg) {
1277 7854b056 bellard
        void *data = CMSG_DATA(cmsg);
1278 7854b056 bellard
        void *target_data = TARGET_CMSG_DATA(target_cmsg);
1279 7854b056 bellard
1280 7854b056 bellard
        int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr));
1281 7854b056 bellard
1282 7854b056 bellard
        space += TARGET_CMSG_SPACE(len);
1283 5a4a898d bellard
        if (space > msg_controllen) {
1284 7854b056 bellard
            space -= TARGET_CMSG_SPACE(len);
1285 31febb71 bellard
            gemu_log("Target cmsg overflow\n");
1286 7854b056 bellard
            break;
1287 7854b056 bellard
        }
1288 7854b056 bellard
1289 7854b056 bellard
        target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level);
1290 7854b056 bellard
        target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type);
1291 7854b056 bellard
        target_cmsg->cmsg_len = tswapl(TARGET_CMSG_LEN(len));
1292 7854b056 bellard
1293 3532fa74 bellard
        if (cmsg->cmsg_level != TARGET_SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
1294 7854b056 bellard
            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);
1295 7854b056 bellard
            memcpy(target_data, data, len);
1296 7854b056 bellard
        } else {
1297 7854b056 bellard
            int *fd = (int *)data;
1298 7854b056 bellard
            int *target_fd = (int *)target_data;
1299 7854b056 bellard
            int i, numfds = len / sizeof(int);
1300 7854b056 bellard
1301 7854b056 bellard
            for (i = 0; i < numfds; i++)
1302 7854b056 bellard
                target_fd[i] = tswap32(fd[i]);
1303 7854b056 bellard
        }
1304 7854b056 bellard
1305 7854b056 bellard
        cmsg = CMSG_NXTHDR(msgh, cmsg);
1306 7854b056 bellard
        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);
1307 7854b056 bellard
    }
1308 5a4a898d bellard
    unlock_user(target_cmsg, target_cmsg_addr, space);
1309 5a4a898d bellard
 the_end:
1310 5a4a898d bellard
    target_msgh->msg_controllen = tswapl(space);
1311 5a4a898d bellard
    return 0;
1312 7854b056 bellard
}
1313 7854b056 bellard
1314 0da46a6e ths
/* do_setsockopt() Must return target values and target errnos. */
1315 992f48a0 blueswir1
static abi_long do_setsockopt(int sockfd, int level, int optname,
1316 2f619698 bellard
                              abi_ulong optval_addr, socklen_t optlen)
1317 7854b056 bellard
{
1318 992f48a0 blueswir1
    abi_long ret;
1319 32407103 j_mayer
    int val;
1320 b975b83b Lionel Landwerlin
    struct ip_mreqn *ip_mreq;
1321 6e3cb58f Lionel Landwerlin
    struct ip_mreq_source *ip_mreq_source;
1322 3b46e624 ths
1323 8853f86e bellard
    switch(level) {
1324 8853f86e bellard
    case SOL_TCP:
1325 7854b056 bellard
        /* TCP options all take an 'int' value.  */
1326 7854b056 bellard
        if (optlen < sizeof(uint32_t))
1327 0da46a6e ths
            return -TARGET_EINVAL;
1328 3b46e624 ths
1329 2f619698 bellard
        if (get_user_u32(val, optval_addr))
1330 2f619698 bellard
            return -TARGET_EFAULT;
1331 8853f86e bellard
        ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1332 8853f86e bellard
        break;
1333 8853f86e bellard
    case SOL_IP:
1334 8853f86e bellard
        switch(optname) {
1335 2efbe911 bellard
        case IP_TOS:
1336 2efbe911 bellard
        case IP_TTL:
1337 8853f86e bellard
        case IP_HDRINCL:
1338 2efbe911 bellard
        case IP_ROUTER_ALERT:
1339 2efbe911 bellard
        case IP_RECVOPTS:
1340 2efbe911 bellard
        case IP_RETOPTS:
1341 2efbe911 bellard
        case IP_PKTINFO:
1342 2efbe911 bellard
        case IP_MTU_DISCOVER:
1343 2efbe911 bellard
        case IP_RECVERR:
1344 2efbe911 bellard
        case IP_RECVTOS:
1345 2efbe911 bellard
#ifdef IP_FREEBIND
1346 2efbe911 bellard
        case IP_FREEBIND:
1347 2efbe911 bellard
#endif
1348 2efbe911 bellard
        case IP_MULTICAST_TTL:
1349 2efbe911 bellard
        case IP_MULTICAST_LOOP:
1350 8853f86e bellard
            val = 0;
1351 8853f86e bellard
            if (optlen >= sizeof(uint32_t)) {
1352 2f619698 bellard
                if (get_user_u32(val, optval_addr))
1353 2f619698 bellard
                    return -TARGET_EFAULT;
1354 8853f86e bellard
            } else if (optlen >= 1) {
1355 2f619698 bellard
                if (get_user_u8(val, optval_addr))
1356 2f619698 bellard
                    return -TARGET_EFAULT;
1357 8853f86e bellard
            }
1358 8853f86e bellard
            ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
1359 8853f86e bellard
            break;
1360 b975b83b Lionel Landwerlin
        case IP_ADD_MEMBERSHIP:
1361 b975b83b Lionel Landwerlin
        case IP_DROP_MEMBERSHIP:
1362 b975b83b Lionel Landwerlin
            if (optlen < sizeof (struct target_ip_mreq) ||
1363 b975b83b Lionel Landwerlin
                optlen > sizeof (struct target_ip_mreqn))
1364 b975b83b Lionel Landwerlin
                return -TARGET_EINVAL;
1365 b975b83b Lionel Landwerlin
1366 b975b83b Lionel Landwerlin
            ip_mreq = (struct ip_mreqn *) alloca(optlen);
1367 b975b83b Lionel Landwerlin
            target_to_host_ip_mreq(ip_mreq, optval_addr, optlen);
1368 b975b83b Lionel Landwerlin
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen));
1369 b975b83b Lionel Landwerlin
            break;
1370 b975b83b Lionel Landwerlin
1371 6e3cb58f Lionel Landwerlin
        case IP_BLOCK_SOURCE:
1372 6e3cb58f Lionel Landwerlin
        case IP_UNBLOCK_SOURCE:
1373 6e3cb58f Lionel Landwerlin
        case IP_ADD_SOURCE_MEMBERSHIP:
1374 6e3cb58f Lionel Landwerlin
        case IP_DROP_SOURCE_MEMBERSHIP:
1375 6e3cb58f Lionel Landwerlin
            if (optlen != sizeof (struct target_ip_mreq_source))
1376 6e3cb58f Lionel Landwerlin
                return -TARGET_EINVAL;
1377 6e3cb58f Lionel Landwerlin
1378 6e3cb58f Lionel Landwerlin
            ip_mreq_source = lock_user(VERIFY_READ, optval_addr, optlen, 1);
1379 6e3cb58f Lionel Landwerlin
            ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq_source, optlen));
1380 6e3cb58f Lionel Landwerlin
            unlock_user (ip_mreq_source, optval_addr, 0);
1381 6e3cb58f Lionel Landwerlin
            break;
1382 6e3cb58f Lionel Landwerlin
1383 8853f86e bellard
        default:
1384 8853f86e bellard
            goto unimplemented;
1385 8853f86e bellard
        }
1386 8853f86e bellard
        break;
1387 3532fa74 bellard
    case TARGET_SOL_SOCKET:
1388 8853f86e bellard
        switch (optname) {
1389 8853f86e bellard
            /* Options with 'int' argument.  */
1390 3532fa74 bellard
        case TARGET_SO_DEBUG:
1391 3532fa74 bellard
                optname = SO_DEBUG;
1392 3532fa74 bellard
                break;
1393 3532fa74 bellard
        case TARGET_SO_REUSEADDR:
1394 3532fa74 bellard
                optname = SO_REUSEADDR;
1395 3532fa74 bellard
                break;
1396 3532fa74 bellard
        case TARGET_SO_TYPE:
1397 3532fa74 bellard
                optname = SO_TYPE;
1398 3532fa74 bellard
                break;
1399 3532fa74 bellard
        case TARGET_SO_ERROR:
1400 3532fa74 bellard
                optname = SO_ERROR;
1401 3532fa74 bellard
                break;
1402 3532fa74 bellard
        case TARGET_SO_DONTROUTE:
1403 3532fa74 bellard
                optname = SO_DONTROUTE;
1404 3532fa74 bellard
                break;
1405 3532fa74 bellard
        case TARGET_SO_BROADCAST:
1406 3532fa74 bellard
                optname = SO_BROADCAST;
1407 3532fa74 bellard
                break;
1408 3532fa74 bellard
        case TARGET_SO_SNDBUF:
1409 3532fa74 bellard
                optname = SO_SNDBUF;
1410 3532fa74 bellard
                break;
1411 3532fa74 bellard
        case TARGET_SO_RCVBUF:
1412 3532fa74 bellard
                optname = SO_RCVBUF;
1413 3532fa74 bellard
                break;
1414 3532fa74 bellard
        case TARGET_SO_KEEPALIVE:
1415 3532fa74 bellard
                optname = SO_KEEPALIVE;
1416 3532fa74 bellard
                break;
1417 3532fa74 bellard
        case TARGET_SO_OOBINLINE:
1418 3532fa74 bellard
                optname = SO_OOBINLINE;
1419 3532fa74 bellard
                break;
1420 3532fa74 bellard
        case TARGET_SO_NO_CHECK:
1421 3532fa74 bellard
                optname = SO_NO_CHECK;
1422 3532fa74 bellard
                break;
1423 3532fa74 bellard
        case TARGET_SO_PRIORITY:
1424 3532fa74 bellard
                optname = SO_PRIORITY;
1425 3532fa74 bellard
                break;
1426 5e83e8e3 bellard
#ifdef SO_BSDCOMPAT
1427 3532fa74 bellard
        case TARGET_SO_BSDCOMPAT:
1428 3532fa74 bellard
                optname = SO_BSDCOMPAT;
1429 3532fa74 bellard
                break;
1430 5e83e8e3 bellard
#endif
1431 3532fa74 bellard
        case TARGET_SO_PASSCRED:
1432 3532fa74 bellard
                optname = SO_PASSCRED;
1433 3532fa74 bellard
                break;
1434 3532fa74 bellard
        case TARGET_SO_TIMESTAMP:
1435 3532fa74 bellard
                optname = SO_TIMESTAMP;
1436 3532fa74 bellard
                break;
1437 3532fa74 bellard
        case TARGET_SO_RCVLOWAT:
1438 3532fa74 bellard
                optname = SO_RCVLOWAT;
1439 3532fa74 bellard
                break;
1440 3532fa74 bellard
        case TARGET_SO_RCVTIMEO:
1441 3532fa74 bellard
                optname = SO_RCVTIMEO;
1442 3532fa74 bellard
                break;
1443 3532fa74 bellard
        case TARGET_SO_SNDTIMEO:
1444 3532fa74 bellard
                optname = SO_SNDTIMEO;
1445 3532fa74 bellard
                break;
1446 8853f86e bellard
            break;
1447 8853f86e bellard
        default:
1448 8853f86e bellard
            goto unimplemented;
1449 8853f86e bellard
        }
1450 3532fa74 bellard
        if (optlen < sizeof(uint32_t))
1451 2f619698 bellard
            return -TARGET_EINVAL;
1452 3532fa74 bellard
1453 2f619698 bellard
        if (get_user_u32(val, optval_addr))
1454 2f619698 bellard
            return -TARGET_EFAULT;
1455 3532fa74 bellard
        ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
1456 8853f86e bellard
        break;
1457 7854b056 bellard
    default:
1458 8853f86e bellard
    unimplemented:
1459 8853f86e bellard
        gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname);
1460 6fa13c17 ths
        ret = -TARGET_ENOPROTOOPT;
1461 7854b056 bellard
    }
1462 8853f86e bellard
    return ret;
1463 7854b056 bellard
}
1464 7854b056 bellard
1465 0da46a6e ths
/* do_getsockopt() Must return target values and target errnos. */
1466 992f48a0 blueswir1
static abi_long do_getsockopt(int sockfd, int level, int optname,
1467 2f619698 bellard
                              abi_ulong optval_addr, abi_ulong optlen)
1468 7854b056 bellard
{
1469 992f48a0 blueswir1
    abi_long ret;
1470 b55266b5 blueswir1
    int len, val;
1471 b55266b5 blueswir1
    socklen_t lv;
1472 8853f86e bellard
1473 8853f86e bellard
    switch(level) {
1474 3532fa74 bellard
    case TARGET_SOL_SOCKET:
1475 f3b974cd Jamie Lentin
        level = SOL_SOCKET;
1476 f3b974cd Jamie Lentin
        switch (optname) {
1477 f3b974cd Jamie Lentin
        /* These don't just return a single integer */
1478 f3b974cd Jamie Lentin
        case TARGET_SO_LINGER:
1479 f3b974cd Jamie Lentin
        case TARGET_SO_RCVTIMEO:
1480 f3b974cd Jamie Lentin
        case TARGET_SO_SNDTIMEO:
1481 f3b974cd Jamie Lentin
        case TARGET_SO_PEERCRED:
1482 f3b974cd Jamie Lentin
        case TARGET_SO_PEERNAME:
1483 f3b974cd Jamie Lentin
            goto unimplemented;
1484 f3b974cd Jamie Lentin
        /* Options with 'int' argument.  */
1485 f3b974cd Jamie Lentin
        case TARGET_SO_DEBUG:
1486 f3b974cd Jamie Lentin
            optname = SO_DEBUG;
1487 f3b974cd Jamie Lentin
            goto int_case;
1488 f3b974cd Jamie Lentin
        case TARGET_SO_REUSEADDR:
1489 f3b974cd Jamie Lentin
            optname = SO_REUSEADDR;
1490 f3b974cd Jamie Lentin
            goto int_case;
1491 f3b974cd Jamie Lentin
        case TARGET_SO_TYPE:
1492 f3b974cd Jamie Lentin
            optname = SO_TYPE;
1493 f3b974cd Jamie Lentin
            goto int_case;
1494 f3b974cd Jamie Lentin
        case TARGET_SO_ERROR:
1495 f3b974cd Jamie Lentin
            optname = SO_ERROR;
1496 f3b974cd Jamie Lentin
            goto int_case;
1497 f3b974cd Jamie Lentin
        case TARGET_SO_DONTROUTE:
1498 f3b974cd Jamie Lentin
            optname = SO_DONTROUTE;
1499 f3b974cd Jamie Lentin
            goto int_case;
1500 f3b974cd Jamie Lentin
        case TARGET_SO_BROADCAST:
1501 f3b974cd Jamie Lentin
            optname = SO_BROADCAST;
1502 f3b974cd Jamie Lentin
            goto int_case;
1503 f3b974cd Jamie Lentin
        case TARGET_SO_SNDBUF:
1504 f3b974cd Jamie Lentin
            optname = SO_SNDBUF;
1505 f3b974cd Jamie Lentin
            goto int_case;
1506 f3b974cd Jamie Lentin
        case TARGET_SO_RCVBUF:
1507 f3b974cd Jamie Lentin
            optname = SO_RCVBUF;
1508 f3b974cd Jamie Lentin
            goto int_case;
1509 f3b974cd Jamie Lentin
        case TARGET_SO_KEEPALIVE:
1510 f3b974cd Jamie Lentin
            optname = SO_KEEPALIVE;
1511 f3b974cd Jamie Lentin
            goto int_case;
1512 f3b974cd Jamie Lentin
        case TARGET_SO_OOBINLINE:
1513 f3b974cd Jamie Lentin
            optname = SO_OOBINLINE;
1514 f3b974cd Jamie Lentin
            goto int_case;
1515 f3b974cd Jamie Lentin
        case TARGET_SO_NO_CHECK:
1516 f3b974cd Jamie Lentin
            optname = SO_NO_CHECK;
1517 f3b974cd Jamie Lentin
            goto int_case;
1518 f3b974cd Jamie Lentin
        case TARGET_SO_PRIORITY:
1519 f3b974cd Jamie Lentin
            optname = SO_PRIORITY;
1520 f3b974cd Jamie Lentin
            goto int_case;
1521 f3b974cd Jamie Lentin
#ifdef SO_BSDCOMPAT
1522 f3b974cd Jamie Lentin
        case TARGET_SO_BSDCOMPAT:
1523 f3b974cd Jamie Lentin
            optname = SO_BSDCOMPAT;
1524 f3b974cd Jamie Lentin
            goto int_case;
1525 f3b974cd Jamie Lentin
#endif
1526 f3b974cd Jamie Lentin
        case TARGET_SO_PASSCRED:
1527 f3b974cd Jamie Lentin
            optname = SO_PASSCRED;
1528 f3b974cd Jamie Lentin
            goto int_case;
1529 f3b974cd Jamie Lentin
        case TARGET_SO_TIMESTAMP:
1530 f3b974cd Jamie Lentin
            optname = SO_TIMESTAMP;
1531 f3b974cd Jamie Lentin
            goto int_case;
1532 f3b974cd Jamie Lentin
        case TARGET_SO_RCVLOWAT:
1533 f3b974cd Jamie Lentin
            optname = SO_RCVLOWAT;
1534 f3b974cd Jamie Lentin
            goto int_case;
1535 8853f86e bellard
        default:
1536 2efbe911 bellard
            goto int_case;
1537 2efbe911 bellard
        }
1538 2efbe911 bellard
        break;
1539 2efbe911 bellard
    case SOL_TCP:
1540 2efbe911 bellard
        /* TCP options all take an 'int' value.  */
1541 2efbe911 bellard
    int_case:
1542 2f619698 bellard
        if (get_user_u32(len, optlen))
1543 2f619698 bellard
            return -TARGET_EFAULT;
1544 2efbe911 bellard
        if (len < 0)
1545 0da46a6e ths
            return -TARGET_EINVAL;
1546 73160d95 Mike Frysinger
        lv = sizeof(lv);
1547 2efbe911 bellard
        ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1548 2efbe911 bellard
        if (ret < 0)
1549 2efbe911 bellard
            return ret;
1550 2efbe911 bellard
        if (len > lv)
1551 2efbe911 bellard
            len = lv;
1552 2f619698 bellard
        if (len == 4) {
1553 2f619698 bellard
            if (put_user_u32(val, optval_addr))
1554 2f619698 bellard
                return -TARGET_EFAULT;
1555 2f619698 bellard
        } else {
1556 2f619698 bellard
            if (put_user_u8(val, optval_addr))
1557 2f619698 bellard
                return -TARGET_EFAULT;
1558 f3b974cd Jamie Lentin
        }
1559 2f619698 bellard
        if (put_user_u32(len, optlen))
1560 2f619698 bellard
            return -TARGET_EFAULT;
1561 2efbe911 bellard
        break;
1562 2efbe911 bellard
    case SOL_IP:
1563 2efbe911 bellard
        switch(optname) {
1564 2efbe911 bellard
        case IP_TOS:
1565 2efbe911 bellard
        case IP_TTL:
1566 2efbe911 bellard
        case IP_HDRINCL:
1567 2efbe911 bellard
        case IP_ROUTER_ALERT:
1568 2efbe911 bellard
        case IP_RECVOPTS:
1569 2efbe911 bellard
        case IP_RETOPTS:
1570 2efbe911 bellard
        case IP_PKTINFO:
1571 2efbe911 bellard
        case IP_MTU_DISCOVER:
1572 2efbe911 bellard
        case IP_RECVERR:
1573 2efbe911 bellard
        case IP_RECVTOS:
1574 2efbe911 bellard
#ifdef IP_FREEBIND
1575 2efbe911 bellard
        case IP_FREEBIND:
1576 2efbe911 bellard
#endif
1577 2efbe911 bellard
        case IP_MULTICAST_TTL:
1578 2efbe911 bellard
        case IP_MULTICAST_LOOP:
1579 2f619698 bellard
            if (get_user_u32(len, optlen))
1580 2f619698 bellard
                return -TARGET_EFAULT;
1581 8853f86e bellard
            if (len < 0)
1582 0da46a6e ths
                return -TARGET_EINVAL;
1583 73160d95 Mike Frysinger
            lv = sizeof(lv);
1584 8853f86e bellard
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
1585 8853f86e bellard
            if (ret < 0)
1586 8853f86e bellard
                return ret;
1587 2efbe911 bellard
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
1588 2efbe911 bellard
                len = 1;
1589 2f619698 bellard
                if (put_user_u32(len, optlen)
1590 2f619698 bellard
                    || put_user_u8(val, optval_addr))
1591 2f619698 bellard
                    return -TARGET_EFAULT;
1592 2efbe911 bellard
            } else {
1593 2efbe911 bellard
                if (len > sizeof(int))
1594 2efbe911 bellard
                    len = sizeof(int);
1595 2f619698 bellard
                if (put_user_u32(len, optlen)
1596 2f619698 bellard
                    || put_user_u32(val, optval_addr))
1597 2f619698 bellard
                    return -TARGET_EFAULT;
1598 2efbe911 bellard
            }
1599 8853f86e bellard
            break;
1600 2efbe911 bellard
        default:
1601 c02f499e ths
            ret = -TARGET_ENOPROTOOPT;
1602 c02f499e ths
            break;
1603 8853f86e bellard
        }
1604 8853f86e bellard
        break;
1605 8853f86e bellard
    default:
1606 8853f86e bellard
    unimplemented:
1607 8853f86e bellard
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
1608 8853f86e bellard
                 level, optname);
1609 c02f499e ths
        ret = -TARGET_EOPNOTSUPP;
1610 8853f86e bellard
        break;
1611 8853f86e bellard
    }
1612 8853f86e bellard
    return ret;
1613 7854b056 bellard
}
1614 7854b056 bellard
1615 579a97f7 bellard
/* FIXME
1616 579a97f7 bellard
 * lock_iovec()/unlock_iovec() have a return code of 0 for success where
1617 579a97f7 bellard
 * other lock functions have a return code of 0 for failure.
1618 579a97f7 bellard
 */
1619 579a97f7 bellard
static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1620 579a97f7 bellard
                           int count, int copy)
1621 53a5960a pbrook
{
1622 53a5960a pbrook
    struct target_iovec *target_vec;
1623 992f48a0 blueswir1
    abi_ulong base;
1624 d732dcb4 balrog
    int i;
1625 53a5960a pbrook
1626 579a97f7 bellard
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1627 579a97f7 bellard
    if (!target_vec)
1628 579a97f7 bellard
        return -TARGET_EFAULT;
1629 53a5960a pbrook
    for(i = 0;i < count; i++) {
1630 53a5960a pbrook
        base = tswapl(target_vec[i].iov_base);
1631 53a5960a pbrook
        vec[i].iov_len = tswapl(target_vec[i].iov_len);
1632 41df8411 bellard
        if (vec[i].iov_len != 0) {
1633 41df8411 bellard
            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1634 d732dcb4 balrog
            /* Don't check lock_user return value. We must call writev even
1635 d732dcb4 balrog
               if a element has invalid base address. */
1636 41df8411 bellard
        } else {
1637 41df8411 bellard
            /* zero length pointer is ignored */
1638 41df8411 bellard
            vec[i].iov_base = NULL;
1639 41df8411 bellard
        }
1640 579a97f7 bellard
    }
1641 579a97f7 bellard
    unlock_user (target_vec, target_addr, 0);
1642 579a97f7 bellard
    return 0;
1643 53a5960a pbrook
}
1644 53a5960a pbrook
1645 579a97f7 bellard
static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1646 579a97f7 bellard
                             int count, int copy)
1647 53a5960a pbrook
{
1648 53a5960a pbrook
    struct target_iovec *target_vec;
1649 992f48a0 blueswir1
    abi_ulong base;
1650 53a5960a pbrook
    int i;
1651 53a5960a pbrook
1652 579a97f7 bellard
    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1653 579a97f7 bellard
    if (!target_vec)
1654 579a97f7 bellard
        return -TARGET_EFAULT;
1655 53a5960a pbrook
    for(i = 0;i < count; i++) {
1656 d732dcb4 balrog
        if (target_vec[i].iov_base) {
1657 d732dcb4 balrog
            base = tswapl(target_vec[i].iov_base);
1658 d732dcb4 balrog
            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
1659 d732dcb4 balrog
        }
1660 53a5960a pbrook
    }
1661 53a5960a pbrook
    unlock_user (target_vec, target_addr, 0);
1662 579a97f7 bellard
1663 579a97f7 bellard
    return 0;
1664 53a5960a pbrook
}
1665 53a5960a pbrook
1666 0da46a6e ths
/* do_socket() Must return target values and target errnos. */
1667 992f48a0 blueswir1
static abi_long do_socket(int domain, int type, int protocol)
1668 3532fa74 bellard
{
1669 3532fa74 bellard
#if defined(TARGET_MIPS)
1670 3532fa74 bellard
    switch(type) {
1671 3532fa74 bellard
    case TARGET_SOCK_DGRAM:
1672 3532fa74 bellard
        type = SOCK_DGRAM;
1673 3532fa74 bellard
        break;
1674 3532fa74 bellard
    case TARGET_SOCK_STREAM:
1675 3532fa74 bellard
        type = SOCK_STREAM;
1676 3532fa74 bellard
        break;
1677 3532fa74 bellard
    case TARGET_SOCK_RAW:
1678 3532fa74 bellard
        type = SOCK_RAW;
1679 3532fa74 bellard
        break;
1680 3532fa74 bellard
    case TARGET_SOCK_RDM:
1681 3532fa74 bellard
        type = SOCK_RDM;
1682 3532fa74 bellard
        break;
1683 3532fa74 bellard
    case TARGET_SOCK_SEQPACKET:
1684 3532fa74 bellard
        type = SOCK_SEQPACKET;
1685 3532fa74 bellard
        break;
1686 3532fa74 bellard
    case TARGET_SOCK_PACKET:
1687 3532fa74 bellard
        type = SOCK_PACKET;
1688 3532fa74 bellard
        break;
1689 3532fa74 bellard
    }
1690 3532fa74 bellard
#endif
1691 12bc92ab balrog
    if (domain == PF_NETLINK)
1692 12bc92ab balrog
        return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */
1693 3532fa74 bellard
    return get_errno(socket(domain, type, protocol));
1694 3532fa74 bellard
}
1695 3532fa74 bellard
1696 0da46a6e ths
/* do_bind() Must return target values and target errnos. */
1697 992f48a0 blueswir1
static abi_long do_bind(int sockfd, abi_ulong target_addr,
1698 992f48a0 blueswir1
                        socklen_t addrlen)
1699 3532fa74 bellard
{
1700 8f7aeaf6 aurel32
    void *addr;
1701 917507b0 Arnaud Patard
    abi_long ret;
1702 8f7aeaf6 aurel32
1703 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1704 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1705 38724253 Blue Swirl
    }
1706 8f7aeaf6 aurel32
1707 607175e0 aurel32
    addr = alloca(addrlen+1);
1708 3b46e624 ths
1709 917507b0 Arnaud Patard
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1710 917507b0 Arnaud Patard
    if (ret)
1711 917507b0 Arnaud Patard
        return ret;
1712 917507b0 Arnaud Patard
1713 3532fa74 bellard
    return get_errno(bind(sockfd, addr, addrlen));
1714 3532fa74 bellard
}
1715 3532fa74 bellard
1716 0da46a6e ths
/* do_connect() Must return target values and target errnos. */
1717 992f48a0 blueswir1
static abi_long do_connect(int sockfd, abi_ulong target_addr,
1718 992f48a0 blueswir1
                           socklen_t addrlen)
1719 3532fa74 bellard
{
1720 8f7aeaf6 aurel32
    void *addr;
1721 917507b0 Arnaud Patard
    abi_long ret;
1722 8f7aeaf6 aurel32
1723 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1724 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1725 38724253 Blue Swirl
    }
1726 8f7aeaf6 aurel32
1727 8f7aeaf6 aurel32
    addr = alloca(addrlen);
1728 3b46e624 ths
1729 917507b0 Arnaud Patard
    ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1730 917507b0 Arnaud Patard
    if (ret)
1731 917507b0 Arnaud Patard
        return ret;
1732 917507b0 Arnaud Patard
1733 3532fa74 bellard
    return get_errno(connect(sockfd, addr, addrlen));
1734 3532fa74 bellard
}
1735 3532fa74 bellard
1736 0da46a6e ths
/* do_sendrecvmsg() Must return target values and target errnos. */
1737 992f48a0 blueswir1
static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
1738 992f48a0 blueswir1
                               int flags, int send)
1739 3532fa74 bellard
{
1740 6de645c7 balrog
    abi_long ret, len;
1741 3532fa74 bellard
    struct target_msghdr *msgp;
1742 3532fa74 bellard
    struct msghdr msg;
1743 3532fa74 bellard
    int count;
1744 3532fa74 bellard
    struct iovec *vec;
1745 992f48a0 blueswir1
    abi_ulong target_vec;
1746 3532fa74 bellard
1747 579a97f7 bellard
    /* FIXME */
1748 579a97f7 bellard
    if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE,
1749 579a97f7 bellard
                          msgp,
1750 579a97f7 bellard
                          target_msg,
1751 579a97f7 bellard
                          send ? 1 : 0))
1752 579a97f7 bellard
        return -TARGET_EFAULT;
1753 3532fa74 bellard
    if (msgp->msg_name) {
1754 3532fa74 bellard
        msg.msg_namelen = tswap32(msgp->msg_namelen);
1755 3532fa74 bellard
        msg.msg_name = alloca(msg.msg_namelen);
1756 917507b0 Arnaud Patard
        ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
1757 3532fa74 bellard
                                msg.msg_namelen);
1758 917507b0 Arnaud Patard
        if (ret) {
1759 917507b0 Arnaud Patard
            unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1760 917507b0 Arnaud Patard
            return ret;
1761 917507b0 Arnaud Patard
        }
1762 3532fa74 bellard
    } else {
1763 3532fa74 bellard
        msg.msg_name = NULL;
1764 3532fa74 bellard
        msg.msg_namelen = 0;
1765 3532fa74 bellard
    }
1766 3532fa74 bellard
    msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
1767 3532fa74 bellard
    msg.msg_control = alloca(msg.msg_controllen);
1768 3532fa74 bellard
    msg.msg_flags = tswap32(msgp->msg_flags);
1769 3b46e624 ths
1770 3532fa74 bellard
    count = tswapl(msgp->msg_iovlen);
1771 3532fa74 bellard
    vec = alloca(count * sizeof(struct iovec));
1772 3532fa74 bellard
    target_vec = tswapl(msgp->msg_iov);
1773 579a97f7 bellard
    lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send);
1774 3532fa74 bellard
    msg.msg_iovlen = count;
1775 3532fa74 bellard
    msg.msg_iov = vec;
1776 3b46e624 ths
1777 3532fa74 bellard
    if (send) {
1778 5a4a898d bellard
        ret = target_to_host_cmsg(&msg, msgp);
1779 5a4a898d bellard
        if (ret == 0)
1780 5a4a898d bellard
            ret = get_errno(sendmsg(fd, &msg, flags));
1781 3532fa74 bellard
    } else {
1782 3532fa74 bellard
        ret = get_errno(recvmsg(fd, &msg, flags));
1783 6de645c7 balrog
        if (!is_error(ret)) {
1784 6de645c7 balrog
            len = ret;
1785 5a4a898d bellard
            ret = host_to_target_cmsg(msgp, &msg);
1786 6de645c7 balrog
            if (!is_error(ret))
1787 6de645c7 balrog
                ret = len;
1788 6de645c7 balrog
        }
1789 3532fa74 bellard
    }
1790 3532fa74 bellard
    unlock_iovec(vec, target_vec, count, !send);
1791 579a97f7 bellard
    unlock_user_struct(msgp, target_msg, send ? 0 : 1);
1792 3532fa74 bellard
    return ret;
1793 3532fa74 bellard
}
1794 3532fa74 bellard
1795 0da46a6e ths
/* do_accept() Must return target values and target errnos. */
1796 992f48a0 blueswir1
static abi_long do_accept(int fd, abi_ulong target_addr,
1797 2f619698 bellard
                          abi_ulong target_addrlen_addr)
1798 1be9e1dc pbrook
{
1799 2f619698 bellard
    socklen_t addrlen;
1800 2f619698 bellard
    void *addr;
1801 992f48a0 blueswir1
    abi_long ret;
1802 1be9e1dc pbrook
1803 917507b0 Arnaud Patard
    if (target_addr == 0)
1804 917507b0 Arnaud Patard
       return get_errno(accept(fd, NULL, NULL));
1805 917507b0 Arnaud Patard
1806 917507b0 Arnaud Patard
    /* linux returns EINVAL if addrlen pointer is invalid */
1807 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1808 917507b0 Arnaud Patard
        return -TARGET_EINVAL;
1809 2f619698 bellard
1810 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1811 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1812 38724253 Blue Swirl
    }
1813 8f7aeaf6 aurel32
1814 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1815 917507b0 Arnaud Patard
        return -TARGET_EINVAL;
1816 917507b0 Arnaud Patard
1817 2f619698 bellard
    addr = alloca(addrlen);
1818 2f619698 bellard
1819 1be9e1dc pbrook
    ret = get_errno(accept(fd, addr, &addrlen));
1820 1be9e1dc pbrook
    if (!is_error(ret)) {
1821 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1822 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1823 2f619698 bellard
            ret = -TARGET_EFAULT;
1824 1be9e1dc pbrook
    }
1825 1be9e1dc pbrook
    return ret;
1826 1be9e1dc pbrook
}
1827 1be9e1dc pbrook
1828 0da46a6e ths
/* do_getpeername() Must return target values and target errnos. */
1829 992f48a0 blueswir1
static abi_long do_getpeername(int fd, abi_ulong target_addr,
1830 2f619698 bellard
                               abi_ulong target_addrlen_addr)
1831 1be9e1dc pbrook
{
1832 2f619698 bellard
    socklen_t addrlen;
1833 2f619698 bellard
    void *addr;
1834 992f48a0 blueswir1
    abi_long ret;
1835 1be9e1dc pbrook
1836 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1837 2f619698 bellard
        return -TARGET_EFAULT;
1838 2f619698 bellard
1839 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1840 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1841 38724253 Blue Swirl
    }
1842 8f7aeaf6 aurel32
1843 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1844 917507b0 Arnaud Patard
        return -TARGET_EFAULT;
1845 917507b0 Arnaud Patard
1846 2f619698 bellard
    addr = alloca(addrlen);
1847 2f619698 bellard
1848 1be9e1dc pbrook
    ret = get_errno(getpeername(fd, addr, &addrlen));
1849 1be9e1dc pbrook
    if (!is_error(ret)) {
1850 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1851 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1852 2f619698 bellard
            ret = -TARGET_EFAULT;
1853 1be9e1dc pbrook
    }
1854 1be9e1dc pbrook
    return ret;
1855 1be9e1dc pbrook
}
1856 1be9e1dc pbrook
1857 0da46a6e ths
/* do_getsockname() Must return target values and target errnos. */
1858 992f48a0 blueswir1
static abi_long do_getsockname(int fd, abi_ulong target_addr,
1859 2f619698 bellard
                               abi_ulong target_addrlen_addr)
1860 1be9e1dc pbrook
{
1861 2f619698 bellard
    socklen_t addrlen;
1862 2f619698 bellard
    void *addr;
1863 992f48a0 blueswir1
    abi_long ret;
1864 1be9e1dc pbrook
1865 2f619698 bellard
    if (get_user_u32(addrlen, target_addrlen_addr))
1866 2f619698 bellard
        return -TARGET_EFAULT;
1867 2f619698 bellard
1868 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1869 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1870 38724253 Blue Swirl
    }
1871 8f7aeaf6 aurel32
1872 917507b0 Arnaud Patard
    if (!access_ok(VERIFY_WRITE, target_addr, addrlen))
1873 917507b0 Arnaud Patard
        return -TARGET_EFAULT;
1874 917507b0 Arnaud Patard
1875 2f619698 bellard
    addr = alloca(addrlen);
1876 2f619698 bellard
1877 1be9e1dc pbrook
    ret = get_errno(getsockname(fd, addr, &addrlen));
1878 1be9e1dc pbrook
    if (!is_error(ret)) {
1879 1be9e1dc pbrook
        host_to_target_sockaddr(target_addr, addr, addrlen);
1880 2f619698 bellard
        if (put_user_u32(addrlen, target_addrlen_addr))
1881 2f619698 bellard
            ret = -TARGET_EFAULT;
1882 1be9e1dc pbrook
    }
1883 1be9e1dc pbrook
    return ret;
1884 1be9e1dc pbrook
}
1885 1be9e1dc pbrook
1886 0da46a6e ths
/* do_socketpair() Must return target values and target errnos. */
1887 992f48a0 blueswir1
static abi_long do_socketpair(int domain, int type, int protocol,
1888 2f619698 bellard
                              abi_ulong target_tab_addr)
1889 1be9e1dc pbrook
{
1890 1be9e1dc pbrook
    int tab[2];
1891 992f48a0 blueswir1
    abi_long ret;
1892 1be9e1dc pbrook
1893 1be9e1dc pbrook
    ret = get_errno(socketpair(domain, type, protocol, tab));
1894 1be9e1dc pbrook
    if (!is_error(ret)) {
1895 2f619698 bellard
        if (put_user_s32(tab[0], target_tab_addr)
1896 2f619698 bellard
            || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
1897 2f619698 bellard
            ret = -TARGET_EFAULT;
1898 1be9e1dc pbrook
    }
1899 1be9e1dc pbrook
    return ret;
1900 1be9e1dc pbrook
}
1901 1be9e1dc pbrook
1902 0da46a6e ths
/* do_sendto() Must return target values and target errnos. */
1903 992f48a0 blueswir1
static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags,
1904 992f48a0 blueswir1
                          abi_ulong target_addr, socklen_t addrlen)
1905 1be9e1dc pbrook
{
1906 1be9e1dc pbrook
    void *addr;
1907 1be9e1dc pbrook
    void *host_msg;
1908 992f48a0 blueswir1
    abi_long ret;
1909 1be9e1dc pbrook
1910 38724253 Blue Swirl
    if ((int)addrlen < 0) {
1911 8f7aeaf6 aurel32
        return -TARGET_EINVAL;
1912 38724253 Blue Swirl
    }
1913 8f7aeaf6 aurel32
1914 579a97f7 bellard
    host_msg = lock_user(VERIFY_READ, msg, len, 1);
1915 579a97f7 bellard
    if (!host_msg)
1916 579a97f7 bellard
        return -TARGET_EFAULT;
1917 1be9e1dc pbrook
    if (target_addr) {
1918 1be9e1dc pbrook
        addr = alloca(addrlen);
1919 917507b0 Arnaud Patard
        ret = target_to_host_sockaddr(addr, target_addr, addrlen);
1920 917507b0 Arnaud Patard
        if (ret) {
1921 917507b0 Arnaud Patard
            unlock_user(host_msg, msg, 0);
1922 917507b0 Arnaud Patard
            return ret;
1923 917507b0 Arnaud Patard
        }
1924 1be9e1dc pbrook
        ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
1925 1be9e1dc pbrook
    } else {
1926 1be9e1dc pbrook
        ret = get_errno(send(fd, host_msg, len, flags));
1927 1be9e1dc pbrook
    }
1928 1be9e1dc pbrook
    unlock_user(host_msg, msg, 0);
1929 1be9e1dc pbrook
    return ret;
1930 1be9e1dc pbrook
}
1931 1be9e1dc pbrook
1932 0da46a6e ths
/* do_recvfrom() Must return target values and target errnos. */
1933 992f48a0 blueswir1
static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
1934 992f48a0 blueswir1
                            abi_ulong target_addr,
1935 992f48a0 blueswir1
                            abi_ulong target_addrlen)
1936 1be9e1dc pbrook
{
1937 1be9e1dc pbrook
    socklen_t addrlen;
1938 1be9e1dc pbrook
    void *addr;
1939 1be9e1dc pbrook
    void *host_msg;
1940 992f48a0 blueswir1
    abi_long ret;
1941 1be9e1dc pbrook
1942 579a97f7 bellard
    host_msg = lock_user(VERIFY_WRITE, msg, len, 0);
1943 579a97f7 bellard
    if (!host_msg)
1944 579a97f7 bellard
        return -TARGET_EFAULT;
1945 1be9e1dc pbrook
    if (target_addr) {
1946 2f619698 bellard
        if (get_user_u32(addrlen, target_addrlen)) {
1947 2f619698 bellard
            ret = -TARGET_EFAULT;
1948 2f619698 bellard
            goto fail;
1949 2f619698 bellard
        }
1950 38724253 Blue Swirl
        if ((int)addrlen < 0) {
1951 8f7aeaf6 aurel32
            ret = -TARGET_EINVAL;
1952 8f7aeaf6 aurel32
            goto fail;
1953 8f7aeaf6 aurel32
        }
1954 1be9e1dc pbrook
        addr = alloca(addrlen);
1955 1be9e1dc pbrook
        ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
1956 1be9e1dc pbrook
    } else {
1957 1be9e1dc pbrook
        addr = NULL; /* To keep compiler quiet.  */
1958 1be9e1dc pbrook
        ret = get_errno(recv(fd, host_msg, len, flags));
1959 1be9e1dc pbrook
    }
1960 1be9e1dc pbrook
    if (!is_error(ret)) {
1961 1be9e1dc pbrook
        if (target_addr) {
1962 1be9e1dc pbrook
            host_to_target_sockaddr(target_addr, addr, addrlen);
1963 2f619698 bellard
            if (put_user_u32(addrlen, target_addrlen)) {
1964 2f619698 bellard
                ret = -TARGET_EFAULT;
1965 2f619698 bellard
                goto fail;
1966 2f619698 bellard
            }
1967 1be9e1dc pbrook
        }
1968 1be9e1dc pbrook
        unlock_user(host_msg, msg, len);
1969 1be9e1dc pbrook
    } else {
1970 2f619698 bellard
fail:
1971 1be9e1dc pbrook
        unlock_user(host_msg, msg, 0);
1972 1be9e1dc pbrook
    }
1973 1be9e1dc pbrook
    return ret;
1974 1be9e1dc pbrook
}
1975 1be9e1dc pbrook
1976 32407103 j_mayer
#ifdef TARGET_NR_socketcall
1977 0da46a6e ths
/* do_socketcall() Must return target values and target errnos. */
1978 992f48a0 blueswir1
static abi_long do_socketcall(int num, abi_ulong vptr)
1979 31e31b8a bellard
{
1980 992f48a0 blueswir1
    abi_long ret;
1981 992f48a0 blueswir1
    const int n = sizeof(abi_ulong);
1982 31e31b8a bellard
1983 31e31b8a bellard
    switch(num) {
1984 31e31b8a bellard
    case SOCKOP_socket:
1985 7854b056 bellard
        {
1986 98818189 Ulrich Hecht
            abi_ulong domain, type, protocol;
1987 2f619698 bellard
1988 98818189 Ulrich Hecht
            if (get_user_ual(domain, vptr)
1989 98818189 Ulrich Hecht
                || get_user_ual(type, vptr + n)
1990 98818189 Ulrich Hecht
                || get_user_ual(protocol, vptr + 2 * n))
1991 2f619698 bellard
                return -TARGET_EFAULT;
1992 2f619698 bellard
1993 3532fa74 bellard
            ret = do_socket(domain, type, protocol);
1994 7854b056 bellard
        }
1995 31e31b8a bellard
        break;
1996 31e31b8a bellard
    case SOCKOP_bind:
1997 7854b056 bellard
        {
1998 98818189 Ulrich Hecht
            abi_ulong sockfd;
1999 2f619698 bellard
            abi_ulong target_addr;
2000 2f619698 bellard
            socklen_t addrlen;
2001 2f619698 bellard
2002 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2003 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
2004 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 2 * n))
2005 2f619698 bellard
                return -TARGET_EFAULT;
2006 2f619698 bellard
2007 3532fa74 bellard
            ret = do_bind(sockfd, target_addr, addrlen);
2008 7854b056 bellard
        }
2009 31e31b8a bellard
        break;
2010 31e31b8a bellard
    case SOCKOP_connect:
2011 7854b056 bellard
        {
2012 98818189 Ulrich Hecht
            abi_ulong sockfd;
2013 2f619698 bellard
            abi_ulong target_addr;
2014 2f619698 bellard
            socklen_t addrlen;
2015 2f619698 bellard
2016 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2017 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
2018 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 2 * n))
2019 2f619698 bellard
                return -TARGET_EFAULT;
2020 2f619698 bellard
2021 3532fa74 bellard
            ret = do_connect(sockfd, target_addr, addrlen);
2022 7854b056 bellard
        }
2023 31e31b8a bellard
        break;
2024 31e31b8a bellard
    case SOCKOP_listen:
2025 7854b056 bellard
        {
2026 98818189 Ulrich Hecht
            abi_ulong sockfd, backlog;
2027 2f619698 bellard
2028 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2029 98818189 Ulrich Hecht
                || get_user_ual(backlog, vptr + n))
2030 2f619698 bellard
                return -TARGET_EFAULT;
2031 2f619698 bellard
2032 7854b056 bellard
            ret = get_errno(listen(sockfd, backlog));
2033 7854b056 bellard
        }
2034 31e31b8a bellard
        break;
2035 31e31b8a bellard
    case SOCKOP_accept:
2036 31e31b8a bellard
        {
2037 98818189 Ulrich Hecht
            abi_ulong sockfd;
2038 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
2039 2f619698 bellard
2040 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2041 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
2042 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
2043 2f619698 bellard
                return -TARGET_EFAULT;
2044 2f619698 bellard
2045 1be9e1dc pbrook
            ret = do_accept(sockfd, target_addr, target_addrlen);
2046 31e31b8a bellard
        }
2047 31e31b8a bellard
        break;
2048 31e31b8a bellard
    case SOCKOP_getsockname:
2049 31e31b8a bellard
        {
2050 98818189 Ulrich Hecht
            abi_ulong sockfd;
2051 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
2052 2f619698 bellard
2053 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2054 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
2055 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
2056 2f619698 bellard
                return -TARGET_EFAULT;
2057 2f619698 bellard
2058 1be9e1dc pbrook
            ret = do_getsockname(sockfd, target_addr, target_addrlen);
2059 31e31b8a bellard
        }
2060 31e31b8a bellard
        break;
2061 31e31b8a bellard
    case SOCKOP_getpeername:
2062 31e31b8a bellard
        {
2063 98818189 Ulrich Hecht
            abi_ulong sockfd;
2064 2f619698 bellard
            abi_ulong target_addr, target_addrlen;
2065 2f619698 bellard
2066 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2067 2f619698 bellard
                || get_user_ual(target_addr, vptr + n)
2068 98818189 Ulrich Hecht
                || get_user_ual(target_addrlen, vptr + 2 * n))
2069 2f619698 bellard
                return -TARGET_EFAULT;
2070 2f619698 bellard
2071 1be9e1dc pbrook
            ret = do_getpeername(sockfd, target_addr, target_addrlen);
2072 31e31b8a bellard
        }
2073 31e31b8a bellard
        break;
2074 31e31b8a bellard
    case SOCKOP_socketpair:
2075 31e31b8a bellard
        {
2076 98818189 Ulrich Hecht
            abi_ulong domain, type, protocol;
2077 2f619698 bellard
            abi_ulong tab;
2078 2f619698 bellard
2079 98818189 Ulrich Hecht
            if (get_user_ual(domain, vptr)
2080 98818189 Ulrich Hecht
                || get_user_ual(type, vptr + n)
2081 98818189 Ulrich Hecht
                || get_user_ual(protocol, vptr + 2 * n)
2082 2f619698 bellard
                || get_user_ual(tab, vptr + 3 * n))
2083 2f619698 bellard
                return -TARGET_EFAULT;
2084 2f619698 bellard
2085 1be9e1dc pbrook
            ret = do_socketpair(domain, type, protocol, tab);
2086 31e31b8a bellard
        }
2087 31e31b8a bellard
        break;
2088 31e31b8a bellard
    case SOCKOP_send:
2089 7854b056 bellard
        {
2090 98818189 Ulrich Hecht
            abi_ulong sockfd;
2091 2f619698 bellard
            abi_ulong msg;
2092 2f619698 bellard
            size_t len;
2093 98818189 Ulrich Hecht
            abi_ulong flags;
2094 2f619698 bellard
2095 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2096 2f619698 bellard
                || get_user_ual(msg, vptr + n)
2097 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
2098 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n))
2099 2f619698 bellard
                return -TARGET_EFAULT;
2100 2f619698 bellard
2101 1be9e1dc pbrook
            ret = do_sendto(sockfd, msg, len, flags, 0, 0);
2102 7854b056 bellard
        }
2103 31e31b8a bellard
        break;
2104 31e31b8a bellard
    case SOCKOP_recv:
2105 7854b056 bellard
        {
2106 98818189 Ulrich Hecht
            abi_ulong sockfd;
2107 2f619698 bellard
            abi_ulong msg;
2108 2f619698 bellard
            size_t len;
2109 98818189 Ulrich Hecht
            abi_ulong flags;
2110 2f619698 bellard
2111 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2112 2f619698 bellard
                || get_user_ual(msg, vptr + n)
2113 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
2114 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n))
2115 2f619698 bellard
                return -TARGET_EFAULT;
2116 2f619698 bellard
2117 1be9e1dc pbrook
            ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
2118 7854b056 bellard
        }
2119 31e31b8a bellard
        break;
2120 31e31b8a bellard
    case SOCKOP_sendto:
2121 7854b056 bellard
        {
2122 98818189 Ulrich Hecht
            abi_ulong sockfd;
2123 2f619698 bellard
            abi_ulong msg;
2124 2f619698 bellard
            size_t len;
2125 98818189 Ulrich Hecht
            abi_ulong flags;
2126 2f619698 bellard
            abi_ulong addr;
2127 2f619698 bellard
            socklen_t addrlen;
2128 2f619698 bellard
2129 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2130 2f619698 bellard
                || get_user_ual(msg, vptr + n)
2131 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
2132 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n)
2133 2f619698 bellard
                || get_user_ual(addr, vptr + 4 * n)
2134 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 5 * n))
2135 2f619698 bellard
                return -TARGET_EFAULT;
2136 2f619698 bellard
2137 1be9e1dc pbrook
            ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
2138 7854b056 bellard
        }
2139 31e31b8a bellard
        break;
2140 31e31b8a bellard
    case SOCKOP_recvfrom:
2141 31e31b8a bellard
        {
2142 98818189 Ulrich Hecht
            abi_ulong sockfd;
2143 2f619698 bellard
            abi_ulong msg;
2144 2f619698 bellard
            size_t len;
2145 98818189 Ulrich Hecht
            abi_ulong flags;
2146 2f619698 bellard
            abi_ulong addr;
2147 2f619698 bellard
            socklen_t addrlen;
2148 2f619698 bellard
2149 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2150 2f619698 bellard
                || get_user_ual(msg, vptr + n)
2151 2f619698 bellard
                || get_user_ual(len, vptr + 2 * n)
2152 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 3 * n)
2153 2f619698 bellard
                || get_user_ual(addr, vptr + 4 * n)
2154 98818189 Ulrich Hecht
                || get_user_ual(addrlen, vptr + 5 * n))
2155 2f619698 bellard
                return -TARGET_EFAULT;
2156 2f619698 bellard
2157 1be9e1dc pbrook
            ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
2158 31e31b8a bellard
        }
2159 31e31b8a bellard
        break;
2160 31e31b8a bellard
    case SOCKOP_shutdown:
2161 7854b056 bellard
        {
2162 98818189 Ulrich Hecht
            abi_ulong sockfd, how;
2163 2f619698 bellard
2164 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2165 98818189 Ulrich Hecht
                || get_user_ual(how, vptr + n))
2166 2f619698 bellard
                return -TARGET_EFAULT;
2167 7854b056 bellard
2168 7854b056 bellard
            ret = get_errno(shutdown(sockfd, how));
2169 7854b056 bellard
        }
2170 31e31b8a bellard
        break;
2171 31e31b8a bellard
    case SOCKOP_sendmsg:
2172 31e31b8a bellard
    case SOCKOP_recvmsg:
2173 1a9353d2 bellard
        {
2174 98818189 Ulrich Hecht
            abi_ulong fd;
2175 992f48a0 blueswir1
            abi_ulong target_msg;
2176 98818189 Ulrich Hecht
            abi_ulong flags;
2177 1a9353d2 bellard
2178 98818189 Ulrich Hecht
            if (get_user_ual(fd, vptr)
2179 2f619698 bellard
                || get_user_ual(target_msg, vptr + n)
2180 98818189 Ulrich Hecht
                || get_user_ual(flags, vptr + 2 * n))
2181 2f619698 bellard
                return -TARGET_EFAULT;
2182 3532fa74 bellard
2183 5fafdf24 ths
            ret = do_sendrecvmsg(fd, target_msg, flags,
2184 3532fa74 bellard
                                 (num == SOCKOP_sendmsg));
2185 1a9353d2 bellard
        }
2186 1a9353d2 bellard
        break;
2187 31e31b8a bellard
    case SOCKOP_setsockopt:
2188 7854b056 bellard
        {
2189 98818189 Ulrich Hecht
            abi_ulong sockfd;
2190 98818189 Ulrich Hecht
            abi_ulong level;
2191 98818189 Ulrich Hecht
            abi_ulong optname;
2192 2f619698 bellard
            abi_ulong optval;
2193 2f619698 bellard
            socklen_t optlen;
2194 2f619698 bellard
2195 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2196 98818189 Ulrich Hecht
                || get_user_ual(level, vptr + n)
2197 98818189 Ulrich Hecht
                || get_user_ual(optname, vptr + 2 * n)
2198 2f619698 bellard
                || get_user_ual(optval, vptr + 3 * n)
2199 98818189 Ulrich Hecht
                || get_user_ual(optlen, vptr + 4 * n))
2200 2f619698 bellard
                return -TARGET_EFAULT;
2201 7854b056 bellard
2202 7854b056 bellard
            ret = do_setsockopt(sockfd, level, optname, optval, optlen);
2203 7854b056 bellard
        }
2204 7854b056 bellard
        break;
2205 31e31b8a bellard
    case SOCKOP_getsockopt:
2206 7854b056 bellard
        {
2207 98818189 Ulrich Hecht
            abi_ulong sockfd;
2208 98818189 Ulrich Hecht
            abi_ulong level;
2209 98818189 Ulrich Hecht
            abi_ulong optname;
2210 2f619698 bellard
            abi_ulong optval;
2211 2f619698 bellard
            socklen_t optlen;
2212 2f619698 bellard
2213 98818189 Ulrich Hecht
            if (get_user_ual(sockfd, vptr)
2214 98818189 Ulrich Hecht
                || get_user_ual(level, vptr + n)
2215 98818189 Ulrich Hecht
                || get_user_ual(optname, vptr + 2 * n)
2216 2f619698 bellard
                || get_user_ual(optval, vptr + 3 * n)
2217 98818189 Ulrich Hecht
                || get_user_ual(optlen, vptr + 4 * n))
2218 2f619698 bellard
                return -TARGET_EFAULT;
2219 7854b056 bellard
2220 2f619698 bellard
            ret = do_getsockopt(sockfd, level, optname, optval, optlen);
2221 7854b056 bellard
        }
2222 7854b056 bellard
        break;
2223 31e31b8a bellard
    default:
2224 31e31b8a bellard
        gemu_log("Unsupported socketcall: %d\n", num);
2225 0da46a6e ths
        ret = -TARGET_ENOSYS;
2226 31e31b8a bellard
        break;
2227 31e31b8a bellard
    }
2228 31e31b8a bellard
    return ret;
2229 31e31b8a bellard
}
2230 32407103 j_mayer
#endif
2231 31e31b8a bellard
2232 8853f86e bellard
#define N_SHM_REGIONS        32
2233 8853f86e bellard
2234 8853f86e bellard
static struct shm_region {
2235 5a4a898d bellard
    abi_ulong        start;
2236 5a4a898d bellard
    abi_ulong        size;
2237 8853f86e bellard
} shm_regions[N_SHM_REGIONS];
2238 8853f86e bellard
2239 3eb6b044 ths
struct target_ipc_perm
2240 3eb6b044 ths
{
2241 992f48a0 blueswir1
    abi_long __key;
2242 992f48a0 blueswir1
    abi_ulong uid;
2243 992f48a0 blueswir1
    abi_ulong gid;
2244 992f48a0 blueswir1
    abi_ulong cuid;
2245 992f48a0 blueswir1
    abi_ulong cgid;
2246 3eb6b044 ths
    unsigned short int mode;
2247 3eb6b044 ths
    unsigned short int __pad1;
2248 3eb6b044 ths
    unsigned short int __seq;
2249 3eb6b044 ths
    unsigned short int __pad2;
2250 992f48a0 blueswir1
    abi_ulong __unused1;
2251 992f48a0 blueswir1
    abi_ulong __unused2;
2252 3eb6b044 ths
};
2253 3eb6b044 ths
2254 3eb6b044 ths
struct target_semid_ds
2255 3eb6b044 ths
{
2256 3eb6b044 ths
  struct target_ipc_perm sem_perm;
2257 992f48a0 blueswir1
  abi_ulong sem_otime;
2258 992f48a0 blueswir1
  abi_ulong __unused1;
2259 992f48a0 blueswir1
  abi_ulong sem_ctime;
2260 992f48a0 blueswir1
  abi_ulong __unused2;
2261 992f48a0 blueswir1
  abi_ulong sem_nsems;
2262 992f48a0 blueswir1
  abi_ulong __unused3;
2263 992f48a0 blueswir1
  abi_ulong __unused4;
2264 3eb6b044 ths
};
2265 3eb6b044 ths
2266 579a97f7 bellard
static inline abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip,
2267 579a97f7 bellard
                                               abi_ulong target_addr)
2268 3eb6b044 ths
{
2269 3eb6b044 ths
    struct target_ipc_perm *target_ip;
2270 3eb6b044 ths
    struct target_semid_ds *target_sd;
2271 3eb6b044 ths
2272 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2273 579a97f7 bellard
        return -TARGET_EFAULT;
2274 e8bbe36c Michael S. Tsirkin
    target_ip = &(target_sd->sem_perm);
2275 3eb6b044 ths
    host_ip->__key = tswapl(target_ip->__key);
2276 3eb6b044 ths
    host_ip->uid = tswapl(target_ip->uid);
2277 3eb6b044 ths
    host_ip->gid = tswapl(target_ip->gid);
2278 3eb6b044 ths
    host_ip->cuid = tswapl(target_ip->cuid);
2279 3eb6b044 ths
    host_ip->cgid = tswapl(target_ip->cgid);
2280 3eb6b044 ths
    host_ip->mode = tswapl(target_ip->mode);
2281 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 0);
2282 579a97f7 bellard
    return 0;
2283 3eb6b044 ths
}
2284 3eb6b044 ths
2285 579a97f7 bellard
static inline abi_long host_to_target_ipc_perm(abi_ulong target_addr,
2286 579a97f7 bellard
                                               struct ipc_perm *host_ip)
2287 3eb6b044 ths
{
2288 3eb6b044 ths
    struct target_ipc_perm *target_ip;
2289 3eb6b044 ths
    struct target_semid_ds *target_sd;
2290 3eb6b044 ths
2291 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2292 579a97f7 bellard
        return -TARGET_EFAULT;
2293 3eb6b044 ths
    target_ip = &(target_sd->sem_perm);
2294 3eb6b044 ths
    target_ip->__key = tswapl(host_ip->__key);
2295 3eb6b044 ths
    target_ip->uid = tswapl(host_ip->uid);
2296 3eb6b044 ths
    target_ip->gid = tswapl(host_ip->gid);
2297 3eb6b044 ths
    target_ip->cuid = tswapl(host_ip->cuid);
2298 3eb6b044 ths
    target_ip->cgid = tswapl(host_ip->cgid);
2299 3eb6b044 ths
    target_ip->mode = tswapl(host_ip->mode);
2300 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 1);
2301 579a97f7 bellard
    return 0;
2302 3eb6b044 ths
}
2303 3eb6b044 ths
2304 579a97f7 bellard
static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd,
2305 579a97f7 bellard
                                               abi_ulong target_addr)
2306 3eb6b044 ths
{
2307 3eb6b044 ths
    struct target_semid_ds *target_sd;
2308 3eb6b044 ths
2309 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2310 579a97f7 bellard
        return -TARGET_EFAULT;
2311 e5289087 aurel32
    if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr))
2312 e5289087 aurel32
        return -TARGET_EFAULT;
2313 3eb6b044 ths
    host_sd->sem_nsems = tswapl(target_sd->sem_nsems);
2314 3eb6b044 ths
    host_sd->sem_otime = tswapl(target_sd->sem_otime);
2315 3eb6b044 ths
    host_sd->sem_ctime = tswapl(target_sd->sem_ctime);
2316 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 0);
2317 579a97f7 bellard
    return 0;
2318 3eb6b044 ths
}
2319 3eb6b044 ths
2320 579a97f7 bellard
static inline abi_long host_to_target_semid_ds(abi_ulong target_addr,
2321 579a97f7 bellard
                                               struct semid_ds *host_sd)
2322 3eb6b044 ths
{
2323 3eb6b044 ths
    struct target_semid_ds *target_sd;
2324 3eb6b044 ths
2325 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2326 579a97f7 bellard
        return -TARGET_EFAULT;
2327 e5289087 aurel32
    if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)))
2328 e5289087 aurel32
        return -TARGET_EFAULT;;
2329 3eb6b044 ths
    target_sd->sem_nsems = tswapl(host_sd->sem_nsems);
2330 3eb6b044 ths
    target_sd->sem_otime = tswapl(host_sd->sem_otime);
2331 3eb6b044 ths
    target_sd->sem_ctime = tswapl(host_sd->sem_ctime);
2332 3eb6b044 ths
    unlock_user_struct(target_sd, target_addr, 1);
2333 579a97f7 bellard
    return 0;
2334 3eb6b044 ths
}
2335 3eb6b044 ths
2336 e5289087 aurel32
struct target_seminfo {
2337 e5289087 aurel32
    int semmap;
2338 e5289087 aurel32
    int semmni;
2339 e5289087 aurel32
    int semmns;
2340 e5289087 aurel32
    int semmnu;
2341 e5289087 aurel32
    int semmsl;
2342 e5289087 aurel32
    int semopm;
2343 e5289087 aurel32
    int semume;
2344 e5289087 aurel32
    int semusz;
2345 e5289087 aurel32
    int semvmx;
2346 e5289087 aurel32
    int semaem;
2347 e5289087 aurel32
};
2348 e5289087 aurel32
2349 e5289087 aurel32
static inline abi_long host_to_target_seminfo(abi_ulong target_addr,
2350 e5289087 aurel32
                                              struct seminfo *host_seminfo)
2351 e5289087 aurel32
{
2352 e5289087 aurel32
    struct target_seminfo *target_seminfo;
2353 e5289087 aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0))
2354 e5289087 aurel32
        return -TARGET_EFAULT;
2355 e5289087 aurel32
    __put_user(host_seminfo->semmap, &target_seminfo->semmap);
2356 e5289087 aurel32
    __put_user(host_seminfo->semmni, &target_seminfo->semmni);
2357 e5289087 aurel32
    __put_user(host_seminfo->semmns, &target_seminfo->semmns);
2358 e5289087 aurel32
    __put_user(host_seminfo->semmnu, &target_seminfo->semmnu);
2359 e5289087 aurel32
    __put_user(host_seminfo->semmsl, &target_seminfo->semmsl);
2360 e5289087 aurel32
    __put_user(host_seminfo->semopm, &target_seminfo->semopm);
2361 e5289087 aurel32
    __put_user(host_seminfo->semume, &target_seminfo->semume);
2362 e5289087 aurel32
    __put_user(host_seminfo->semusz, &target_seminfo->semusz);
2363 e5289087 aurel32
    __put_user(host_seminfo->semvmx, &target_seminfo->semvmx);
2364 e5289087 aurel32
    __put_user(host_seminfo->semaem, &target_seminfo->semaem);
2365 e5289087 aurel32
    unlock_user_struct(target_seminfo, target_addr, 1);
2366 e5289087 aurel32
    return 0;
2367 e5289087 aurel32
}
2368 e5289087 aurel32
2369 fa294816 ths
union semun {
2370 fa294816 ths
        int val;
2371 3eb6b044 ths
        struct semid_ds *buf;
2372 fa294816 ths
        unsigned short *array;
2373 e5289087 aurel32
        struct seminfo *__buf;
2374 fa294816 ths
};
2375 fa294816 ths
2376 3eb6b044 ths
union target_semun {
2377 3eb6b044 ths
        int val;
2378 e5289087 aurel32
        abi_ulong buf;
2379 e5289087 aurel32
        abi_ulong array;
2380 e5289087 aurel32
        abi_ulong __buf;
2381 3eb6b044 ths
};
2382 3eb6b044 ths
2383 e5289087 aurel32
static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array,
2384 e5289087 aurel32
                                               abi_ulong target_addr)
2385 3eb6b044 ths
{
2386 e5289087 aurel32
    int nsems;
2387 e5289087 aurel32
    unsigned short *array;
2388 e5289087 aurel32
    union semun semun;
2389 e5289087 aurel32
    struct semid_ds semid_ds;
2390 e5289087 aurel32
    int i, ret;
2391 3eb6b044 ths
2392 e5289087 aurel32
    semun.buf = &semid_ds;
2393 e5289087 aurel32
2394 e5289087 aurel32
    ret = semctl(semid, 0, IPC_STAT, semun);
2395 e5289087 aurel32
    if (ret == -1)
2396 e5289087 aurel32
        return get_errno(ret);
2397 e5289087 aurel32
2398 e5289087 aurel32
    nsems = semid_ds.sem_nsems;
2399 e5289087 aurel32
2400 e5289087 aurel32
    *host_array = malloc(nsems*sizeof(unsigned short));
2401 e5289087 aurel32
    array = lock_user(VERIFY_READ, target_addr,
2402 e5289087 aurel32
                      nsems*sizeof(unsigned short), 1);
2403 e5289087 aurel32
    if (!array)
2404 e5289087 aurel32
        return -TARGET_EFAULT;
2405 e5289087 aurel32
2406 e5289087 aurel32
    for(i=0; i<nsems; i++) {
2407 e5289087 aurel32
        __get_user((*host_array)[i], &array[i]);
2408 3eb6b044 ths
    }
2409 e5289087 aurel32
    unlock_user(array, target_addr, 0);
2410 e5289087 aurel32
2411 579a97f7 bellard
    return 0;
2412 3eb6b044 ths
}
2413 3eb6b044 ths
2414 e5289087 aurel32
static inline abi_long host_to_target_semarray(int semid, abi_ulong target_addr,
2415 e5289087 aurel32
                                               unsigned short **host_array)
2416 3eb6b044 ths
{
2417 e5289087 aurel32
    int nsems;
2418 e5289087 aurel32
    unsigned short *array;
2419 e5289087 aurel32
    union semun semun;
2420 e5289087 aurel32
    struct semid_ds semid_ds;
2421 e5289087 aurel32
    int i, ret;
2422 3eb6b044 ths
2423 e5289087 aurel32
    semun.buf = &semid_ds;
2424 e5289087 aurel32
2425 e5289087 aurel32
    ret = semctl(semid, 0, IPC_STAT, semun);
2426 e5289087 aurel32
    if (ret == -1)
2427 e5289087 aurel32
        return get_errno(ret);
2428 e5289087 aurel32
2429 e5289087 aurel32
    nsems = semid_ds.sem_nsems;
2430 e5289087 aurel32
2431 e5289087 aurel32
    array = lock_user(VERIFY_WRITE, target_addr,
2432 e5289087 aurel32
                      nsems*sizeof(unsigned short), 0);
2433 e5289087 aurel32
    if (!array)
2434 e5289087 aurel32
        return -TARGET_EFAULT;
2435 e5289087 aurel32
2436 e5289087 aurel32
    for(i=0; i<nsems; i++) {
2437 e5289087 aurel32
        __put_user((*host_array)[i], &array[i]);
2438 3eb6b044 ths
    }
2439 e5289087 aurel32
    free(*host_array);
2440 e5289087 aurel32
    unlock_user(array, target_addr, 1);
2441 e5289087 aurel32
2442 579a97f7 bellard
    return 0;
2443 3eb6b044 ths
}
2444 3eb6b044 ths
2445 e5289087 aurel32
static inline abi_long do_semctl(int semid, int semnum, int cmd,
2446 e5289087 aurel32
                                 union target_semun target_su)
2447 3eb6b044 ths
{
2448 3eb6b044 ths
    union semun arg;
2449 3eb6b044 ths
    struct semid_ds dsarg;
2450 7b8118e8 vibi sreenivasan
    unsigned short *array = NULL;
2451 e5289087 aurel32
    struct seminfo seminfo;
2452 e5289087 aurel32
    abi_long ret = -TARGET_EINVAL;
2453 e5289087 aurel32
    abi_long err;
2454 e5289087 aurel32
    cmd &= 0xff;
2455 3eb6b044 ths
2456 3eb6b044 ths
    switch( cmd ) {
2457 3eb6b044 ths
        case GETVAL:
2458 3eb6b044 ths
        case SETVAL:
2459 e5289087 aurel32
            arg.val = tswapl(target_su.val);
2460 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2461 e5289087 aurel32
            target_su.val = tswapl(arg.val);
2462 3eb6b044 ths
            break;
2463 3eb6b044 ths
        case GETALL:
2464 3eb6b044 ths
        case SETALL:
2465 e5289087 aurel32
            err = target_to_host_semarray(semid, &array, target_su.array);
2466 e5289087 aurel32
            if (err)
2467 e5289087 aurel32
                return err;
2468 e5289087 aurel32
            arg.array = array;
2469 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2470 e5289087 aurel32
            err = host_to_target_semarray(semid, target_su.array, &array);
2471 e5289087 aurel32
            if (err)
2472 e5289087 aurel32
                return err;
2473 3eb6b044 ths
            break;
2474 3eb6b044 ths
        case IPC_STAT:
2475 3eb6b044 ths
        case IPC_SET:
2476 e5289087 aurel32
        case SEM_STAT:
2477 e5289087 aurel32
            err = target_to_host_semid_ds(&dsarg, target_su.buf);
2478 e5289087 aurel32
            if (err)
2479 e5289087 aurel32
                return err;
2480 e5289087 aurel32
            arg.buf = &dsarg;
2481 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2482 e5289087 aurel32
            err = host_to_target_semid_ds(target_su.buf, &dsarg);
2483 e5289087 aurel32
            if (err)
2484 e5289087 aurel32
                return err;
2485 e5289087 aurel32
            break;
2486 e5289087 aurel32
        case IPC_INFO:
2487 e5289087 aurel32
        case SEM_INFO:
2488 e5289087 aurel32
            arg.__buf = &seminfo;
2489 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, arg));
2490 e5289087 aurel32
            err = host_to_target_seminfo(target_su.__buf, &seminfo);
2491 e5289087 aurel32
            if (err)
2492 e5289087 aurel32
                return err;
2493 e5289087 aurel32
            break;
2494 e5289087 aurel32
        case IPC_RMID:
2495 e5289087 aurel32
        case GETPID:
2496 e5289087 aurel32
        case GETNCNT:
2497 e5289087 aurel32
        case GETZCNT:
2498 e5289087 aurel32
            ret = get_errno(semctl(semid, semnum, cmd, NULL));
2499 3eb6b044 ths
            break;
2500 3eb6b044 ths
    }
2501 3eb6b044 ths
2502 3eb6b044 ths
    return ret;
2503 3eb6b044 ths
}
2504 3eb6b044 ths
2505 e5289087 aurel32
struct target_sembuf {
2506 e5289087 aurel32
    unsigned short sem_num;
2507 e5289087 aurel32
    short sem_op;
2508 e5289087 aurel32
    short sem_flg;
2509 e5289087 aurel32
};
2510 e5289087 aurel32
2511 e5289087 aurel32
static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf,
2512 e5289087 aurel32
                                             abi_ulong target_addr,
2513 e5289087 aurel32
                                             unsigned nsops)
2514 e5289087 aurel32
{
2515 e5289087 aurel32
    struct target_sembuf *target_sembuf;
2516 e5289087 aurel32
    int i;
2517 e5289087 aurel32
2518 e5289087 aurel32
    target_sembuf = lock_user(VERIFY_READ, target_addr,
2519 e5289087 aurel32
                              nsops*sizeof(struct target_sembuf), 1);
2520 e5289087 aurel32
    if (!target_sembuf)
2521 e5289087 aurel32
        return -TARGET_EFAULT;
2522 e5289087 aurel32
2523 e5289087 aurel32
    for(i=0; i<nsops; i++) {
2524 e5289087 aurel32
        __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num);
2525 e5289087 aurel32
        __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op);
2526 e5289087 aurel32
        __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg);
2527 e5289087 aurel32
    }
2528 e5289087 aurel32
2529 e5289087 aurel32
    unlock_user(target_sembuf, target_addr, 0);
2530 e5289087 aurel32
2531 e5289087 aurel32
    return 0;
2532 e5289087 aurel32
}
2533 e5289087 aurel32
2534 e5289087 aurel32
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
2535 e5289087 aurel32
{
2536 e5289087 aurel32
    struct sembuf sops[nsops];
2537 e5289087 aurel32
2538 e5289087 aurel32
    if (target_to_host_sembuf(sops, ptr, nsops))
2539 e5289087 aurel32
        return -TARGET_EFAULT;
2540 e5289087 aurel32
2541 e5289087 aurel32
    return semop(semid, sops, nsops);
2542 e5289087 aurel32
}
2543 e5289087 aurel32
2544 1bc012f6 ths
struct target_msqid_ds
2545 1bc012f6 ths
{
2546 1c54ff97 aurel32
    struct target_ipc_perm msg_perm;
2547 1c54ff97 aurel32
    abi_ulong msg_stime;
2548 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2549 1c54ff97 aurel32
    abi_ulong __unused1;
2550 1c54ff97 aurel32
#endif
2551 1c54ff97 aurel32
    abi_ulong msg_rtime;
2552 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2553 1c54ff97 aurel32
    abi_ulong __unused2;
2554 1c54ff97 aurel32
#endif
2555 1c54ff97 aurel32
    abi_ulong msg_ctime;
2556 1c54ff97 aurel32
#if TARGET_ABI_BITS == 32
2557 1c54ff97 aurel32
    abi_ulong __unused3;
2558 1c54ff97 aurel32
#endif
2559 1c54ff97 aurel32
    abi_ulong __msg_cbytes;
2560 1c54ff97 aurel32
    abi_ulong msg_qnum;
2561 1c54ff97 aurel32
    abi_ulong msg_qbytes;
2562 1c54ff97 aurel32
    abi_ulong msg_lspid;
2563 1c54ff97 aurel32
    abi_ulong msg_lrpid;
2564 1c54ff97 aurel32
    abi_ulong __unused4;
2565 1c54ff97 aurel32
    abi_ulong __unused5;
2566 1bc012f6 ths
};
2567 1bc012f6 ths
2568 579a97f7 bellard
static inline abi_long target_to_host_msqid_ds(struct msqid_ds *host_md,
2569 579a97f7 bellard
                                               abi_ulong target_addr)
2570 1bc012f6 ths
{
2571 1bc012f6 ths
    struct target_msqid_ds *target_md;
2572 1bc012f6 ths
2573 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1))
2574 579a97f7 bellard
        return -TARGET_EFAULT;
2575 1c54ff97 aurel32
    if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr))
2576 1c54ff97 aurel32
        return -TARGET_EFAULT;
2577 1bc012f6 ths
    host_md->msg_stime = tswapl(target_md->msg_stime);
2578 1bc012f6 ths
    host_md->msg_rtime = tswapl(target_md->msg_rtime);
2579 1bc012f6 ths
    host_md->msg_ctime = tswapl(target_md->msg_ctime);
2580 1bc012f6 ths
    host_md->__msg_cbytes = tswapl(target_md->__msg_cbytes);
2581 1bc012f6 ths
    host_md->msg_qnum = tswapl(target_md->msg_qnum);
2582 1bc012f6 ths
    host_md->msg_qbytes = tswapl(target_md->msg_qbytes);
2583 1bc012f6 ths
    host_md->msg_lspid = tswapl(target_md->msg_lspid);
2584 1bc012f6 ths
    host_md->msg_lrpid = tswapl(target_md->msg_lrpid);
2585 1bc012f6 ths
    unlock_user_struct(target_md, target_addr, 0);
2586 579a97f7 bellard
    return 0;
2587 1bc012f6 ths
}
2588 1bc012f6 ths
2589 579a97f7 bellard
static inline abi_long host_to_target_msqid_ds(abi_ulong target_addr,
2590 579a97f7 bellard
                                               struct msqid_ds *host_md)
2591 1bc012f6 ths
{
2592 1bc012f6 ths
    struct target_msqid_ds *target_md;
2593 1bc012f6 ths
2594 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0))
2595 579a97f7 bellard
        return -TARGET_EFAULT;
2596 1c54ff97 aurel32
    if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm)))
2597 1c54ff97 aurel32
        return -TARGET_EFAULT;
2598 1bc012f6 ths
    target_md->msg_stime = tswapl(host_md->msg_stime);
2599 1bc012f6 ths
    target_md->msg_rtime = tswapl(host_md->msg_rtime);
2600 1bc012f6 ths
    target_md->msg_ctime = tswapl(host_md->msg_ctime);
2601 1bc012f6 ths
    target_md->__msg_cbytes = tswapl(host_md->__msg_cbytes);
2602 1bc012f6 ths
    target_md->msg_qnum = tswapl(host_md->msg_qnum);
2603 1bc012f6 ths
    target_md->msg_qbytes = tswapl(host_md->msg_qbytes);
2604 1bc012f6 ths
    target_md->msg_lspid = tswapl(host_md->msg_lspid);
2605 1bc012f6 ths
    target_md->msg_lrpid = tswapl(host_md->msg_lrpid);
2606 1bc012f6 ths
    unlock_user_struct(target_md, target_addr, 1);
2607 579a97f7 bellard
    return 0;
2608 1bc012f6 ths
}
2609 1bc012f6 ths
2610 1c54ff97 aurel32
struct target_msginfo {
2611 1c54ff97 aurel32
    int msgpool;
2612 1c54ff97 aurel32
    int msgmap;
2613 1c54ff97 aurel32
    int msgmax;
2614 1c54ff97 aurel32
    int msgmnb;
2615 1c54ff97 aurel32
    int msgmni;
2616 1c54ff97 aurel32
    int msgssz;
2617 1c54ff97 aurel32
    int msgtql;
2618 1c54ff97 aurel32
    unsigned short int msgseg;
2619 1c54ff97 aurel32
};
2620 1c54ff97 aurel32
2621 1c54ff97 aurel32
static inline abi_long host_to_target_msginfo(abi_ulong target_addr,
2622 1c54ff97 aurel32
                                              struct msginfo *host_msginfo)
2623 1c54ff97 aurel32
{
2624 1c54ff97 aurel32
    struct target_msginfo *target_msginfo;
2625 1c54ff97 aurel32
    if (!lock_user_struct(VERIFY_WRITE, target_msginfo, target_addr, 0))
2626 1c54ff97 aurel32
        return -TARGET_EFAULT;
2627 1c54ff97 aurel32
    __put_user(host_msginfo->msgpool, &target_msginfo->msgpool);
2628 1c54ff97 aurel32
    __put_user(host_msginfo->msgmap, &target_msginfo->msgmap);
2629 1c54ff97 aurel32
    __put_user(host_msginfo->msgmax, &target_msginfo->msgmax);
2630 1c54ff97 aurel32
    __put_user(host_msginfo->msgmnb, &target_msginfo->msgmnb);
2631 1c54ff97 aurel32
    __put_user(host_msginfo->msgmni, &target_msginfo->msgmni);
2632 1c54ff97 aurel32
    __put_user(host_msginfo->msgssz, &target_msginfo->msgssz);
2633 1c54ff97 aurel32
    __put_user(host_msginfo->msgtql, &target_msginfo->msgtql);
2634 1c54ff97 aurel32
    __put_user(host_msginfo->msgseg, &target_msginfo->msgseg);
2635 1c54ff97 aurel32
    unlock_user_struct(target_msginfo, target_addr, 1);
2636 00b229ac aurel32
    return 0;
2637 1c54ff97 aurel32
}
2638 1c54ff97 aurel32
2639 1c54ff97 aurel32
static inline abi_long do_msgctl(int msgid, int cmd, abi_long ptr)
2640 1bc012f6 ths
{
2641 1bc012f6 ths
    struct msqid_ds dsarg;
2642 1c54ff97 aurel32
    struct msginfo msginfo;
2643 1c54ff97 aurel32
    abi_long ret = -TARGET_EINVAL;
2644 1c54ff97 aurel32
2645 1c54ff97 aurel32
    cmd &= 0xff;
2646 1c54ff97 aurel32
2647 1c54ff97 aurel32
    switch (cmd) {
2648 1bc012f6 ths
    case IPC_STAT:
2649 1bc012f6 ths
    case IPC_SET:
2650 1c54ff97 aurel32
    case MSG_STAT:
2651 1c54ff97 aurel32
        if (target_to_host_msqid_ds(&dsarg,ptr))
2652 1c54ff97 aurel32
            return -TARGET_EFAULT;
2653 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, &dsarg));
2654 1c54ff97 aurel32
        if (host_to_target_msqid_ds(ptr,&dsarg))
2655 1c54ff97 aurel32
            return -TARGET_EFAULT;
2656 1c54ff97 aurel32
        break;
2657 1c54ff97 aurel32
    case IPC_RMID:
2658 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, NULL));
2659 1c54ff97 aurel32
        break;
2660 1c54ff97 aurel32
    case IPC_INFO:
2661 1c54ff97 aurel32
    case MSG_INFO:
2662 1c54ff97 aurel32
        ret = get_errno(msgctl(msgid, cmd, (struct msqid_ds *)&msginfo));
2663 1c54ff97 aurel32
        if (host_to_target_msginfo(ptr, &msginfo))
2664 1c54ff97 aurel32
            return -TARGET_EFAULT;
2665 1c54ff97 aurel32
        break;
2666 1bc012f6 ths
    }
2667 1c54ff97 aurel32
2668 1bc012f6 ths
    return ret;
2669 1bc012f6 ths
}
2670 1bc012f6 ths
2671 1bc012f6 ths
struct target_msgbuf {
2672 1c54ff97 aurel32
    abi_long mtype;
2673 1c54ff97 aurel32
    char        mtext[1];
2674 1bc012f6 ths
};
2675 1bc012f6 ths
2676 992f48a0 blueswir1
static inline abi_long do_msgsnd(int msqid, abi_long msgp,
2677 992f48a0 blueswir1
                                 unsigned int msgsz, int msgflg)
2678 1bc012f6 ths
{
2679 1bc012f6 ths
    struct target_msgbuf *target_mb;
2680 1bc012f6 ths
    struct msgbuf *host_mb;
2681 992f48a0 blueswir1
    abi_long ret = 0;
2682 1bc012f6 ths
2683 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0))
2684 579a97f7 bellard
        return -TARGET_EFAULT;
2685 1bc012f6 ths
    host_mb = malloc(msgsz+sizeof(long));
2686 1c54ff97 aurel32
    host_mb->mtype = (abi_long) tswapl(target_mb->mtype);
2687 1c54ff97 aurel32
    memcpy(host_mb->mtext, target_mb->mtext, msgsz);
2688 1bc012f6 ths
    ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg));
2689 1bc012f6 ths
    free(host_mb);
2690 1bc012f6 ths
    unlock_user_struct(target_mb, msgp, 0);
2691 1bc012f6 ths
2692 1bc012f6 ths
    return ret;
2693 1bc012f6 ths
}
2694 1bc012f6 ths
2695 992f48a0 blueswir1
static inline abi_long do_msgrcv(int msqid, abi_long msgp,
2696 1c54ff97 aurel32
                                 unsigned int msgsz, abi_long msgtyp,
2697 992f48a0 blueswir1
                                 int msgflg)
2698 1bc012f6 ths
{
2699 1bc012f6 ths
    struct target_msgbuf *target_mb;
2700 579a97f7 bellard
    char *target_mtext;
2701 1bc012f6 ths
    struct msgbuf *host_mb;
2702 992f48a0 blueswir1
    abi_long ret = 0;
2703 1bc012f6 ths
2704 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
2705 579a97f7 bellard
        return -TARGET_EFAULT;
2706 1c54ff97 aurel32
2707 1bc012f6 ths
    host_mb = malloc(msgsz+sizeof(long));
2708 1c54ff97 aurel32
    ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapl(msgtyp), msgflg));
2709 1c54ff97 aurel32
2710 579a97f7 bellard
    if (ret > 0) {
2711 579a97f7 bellard
        abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
2712 579a97f7 bellard
        target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0);
2713 579a97f7 bellard
        if (!target_mtext) {
2714 579a97f7 bellard
            ret = -TARGET_EFAULT;
2715 579a97f7 bellard
            goto end;
2716 579a97f7 bellard
        }
2717 1c54ff97 aurel32
        memcpy(target_mb->mtext, host_mb->mtext, ret);
2718 579a97f7 bellard
        unlock_user(target_mtext, target_mtext_addr, ret);
2719 579a97f7 bellard
    }
2720 1c54ff97 aurel32
2721 1bc012f6 ths
    target_mb->mtype = tswapl(host_mb->mtype);
2722 1bc012f6 ths
    free(host_mb);
2723 1bc012f6 ths
2724 579a97f7 bellard
end:
2725 579a97f7 bellard
    if (target_mb)
2726 579a97f7 bellard
        unlock_user_struct(target_mb, msgp, 1);
2727 1bc012f6 ths
    return ret;
2728 1bc012f6 ths
}
2729 1bc012f6 ths
2730 88a8c984 Riku Voipio
struct target_shmid_ds
2731 88a8c984 Riku Voipio
{
2732 88a8c984 Riku Voipio
    struct target_ipc_perm shm_perm;
2733 88a8c984 Riku Voipio
    abi_ulong shm_segsz;
2734 88a8c984 Riku Voipio
    abi_ulong shm_atime;
2735 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2736 88a8c984 Riku Voipio
    abi_ulong __unused1;
2737 88a8c984 Riku Voipio
#endif
2738 88a8c984 Riku Voipio
    abi_ulong shm_dtime;
2739 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2740 88a8c984 Riku Voipio
    abi_ulong __unused2;
2741 88a8c984 Riku Voipio
#endif
2742 88a8c984 Riku Voipio
    abi_ulong shm_ctime;
2743 88a8c984 Riku Voipio
#if TARGET_ABI_BITS == 32
2744 88a8c984 Riku Voipio
    abi_ulong __unused3;
2745 88a8c984 Riku Voipio
#endif
2746 88a8c984 Riku Voipio
    int shm_cpid;
2747 88a8c984 Riku Voipio
    int shm_lpid;
2748 88a8c984 Riku Voipio
    abi_ulong shm_nattch;
2749 88a8c984 Riku Voipio
    unsigned long int __unused4;
2750 88a8c984 Riku Voipio
    unsigned long int __unused5;
2751 88a8c984 Riku Voipio
};
2752 88a8c984 Riku Voipio
2753 88a8c984 Riku Voipio
static inline abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd,
2754 88a8c984 Riku Voipio
                                               abi_ulong target_addr)
2755 88a8c984 Riku Voipio
{
2756 88a8c984 Riku Voipio
    struct target_shmid_ds *target_sd;
2757 88a8c984 Riku Voipio
2758 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1))
2759 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2760 88a8c984 Riku Voipio
    if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr))
2761 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2762 88a8c984 Riku Voipio
    __get_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2763 88a8c984 Riku Voipio
    __get_user(host_sd->shm_atime, &target_sd->shm_atime);
2764 88a8c984 Riku Voipio
    __get_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2765 88a8c984 Riku Voipio
    __get_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2766 88a8c984 Riku Voipio
    __get_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2767 88a8c984 Riku Voipio
    __get_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2768 88a8c984 Riku Voipio
    __get_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2769 88a8c984 Riku Voipio
    unlock_user_struct(target_sd, target_addr, 0);
2770 88a8c984 Riku Voipio
    return 0;
2771 88a8c984 Riku Voipio
}
2772 88a8c984 Riku Voipio
2773 88a8c984 Riku Voipio
static inline abi_long host_to_target_shmid_ds(abi_ulong target_addr,
2774 88a8c984 Riku Voipio
                                               struct shmid_ds *host_sd)
2775 88a8c984 Riku Voipio
{
2776 88a8c984 Riku Voipio
    struct target_shmid_ds *target_sd;
2777 88a8c984 Riku Voipio
2778 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0))
2779 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2780 88a8c984 Riku Voipio
    if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm)))
2781 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2782 88a8c984 Riku Voipio
    __put_user(host_sd->shm_segsz, &target_sd->shm_segsz);
2783 88a8c984 Riku Voipio
    __put_user(host_sd->shm_atime, &target_sd->shm_atime);
2784 88a8c984 Riku Voipio
    __put_user(host_sd->shm_dtime, &target_sd->shm_dtime);
2785 88a8c984 Riku Voipio
    __put_user(host_sd->shm_ctime, &target_sd->shm_ctime);
2786 88a8c984 Riku Voipio
    __put_user(host_sd->shm_cpid, &target_sd->shm_cpid);
2787 88a8c984 Riku Voipio
    __put_user(host_sd->shm_lpid, &target_sd->shm_lpid);
2788 88a8c984 Riku Voipio
    __put_user(host_sd->shm_nattch, &target_sd->shm_nattch);
2789 88a8c984 Riku Voipio
    unlock_user_struct(target_sd, target_addr, 1);
2790 88a8c984 Riku Voipio
    return 0;
2791 88a8c984 Riku Voipio
}
2792 88a8c984 Riku Voipio
2793 88a8c984 Riku Voipio
struct  target_shminfo {
2794 88a8c984 Riku Voipio
    abi_ulong shmmax;
2795 88a8c984 Riku Voipio
    abi_ulong shmmin;
2796 88a8c984 Riku Voipio
    abi_ulong shmmni;
2797 88a8c984 Riku Voipio
    abi_ulong shmseg;
2798 88a8c984 Riku Voipio
    abi_ulong shmall;
2799 88a8c984 Riku Voipio
};
2800 88a8c984 Riku Voipio
2801 88a8c984 Riku Voipio
static inline abi_long host_to_target_shminfo(abi_ulong target_addr,
2802 88a8c984 Riku Voipio
                                              struct shminfo *host_shminfo)
2803 88a8c984 Riku Voipio
{
2804 88a8c984 Riku Voipio
    struct target_shminfo *target_shminfo;
2805 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_shminfo, target_addr, 0))
2806 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2807 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmax, &target_shminfo->shmmax);
2808 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmin, &target_shminfo->shmmin);
2809 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmmni, &target_shminfo->shmmni);
2810 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmseg, &target_shminfo->shmseg);
2811 88a8c984 Riku Voipio
    __put_user(host_shminfo->shmall, &target_shminfo->shmall);
2812 88a8c984 Riku Voipio
    unlock_user_struct(target_shminfo, target_addr, 1);
2813 88a8c984 Riku Voipio
    return 0;
2814 88a8c984 Riku Voipio
}
2815 88a8c984 Riku Voipio
2816 88a8c984 Riku Voipio
struct target_shm_info {
2817 88a8c984 Riku Voipio
    int used_ids;
2818 88a8c984 Riku Voipio
    abi_ulong shm_tot;
2819 88a8c984 Riku Voipio
    abi_ulong shm_rss;
2820 88a8c984 Riku Voipio
    abi_ulong shm_swp;
2821 88a8c984 Riku Voipio
    abi_ulong swap_attempts;
2822 88a8c984 Riku Voipio
    abi_ulong swap_successes;
2823 88a8c984 Riku Voipio
};
2824 88a8c984 Riku Voipio
2825 88a8c984 Riku Voipio
static inline abi_long host_to_target_shm_info(abi_ulong target_addr,
2826 88a8c984 Riku Voipio
                                               struct shm_info *host_shm_info)
2827 88a8c984 Riku Voipio
{
2828 88a8c984 Riku Voipio
    struct target_shm_info *target_shm_info;
2829 88a8c984 Riku Voipio
    if (!lock_user_struct(VERIFY_WRITE, target_shm_info, target_addr, 0))
2830 88a8c984 Riku Voipio
        return -TARGET_EFAULT;
2831 88a8c984 Riku Voipio
    __put_user(host_shm_info->used_ids, &target_shm_info->used_ids);
2832 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_tot, &target_shm_info->shm_tot);
2833 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_rss, &target_shm_info->shm_rss);
2834 88a8c984 Riku Voipio
    __put_user(host_shm_info->shm_swp, &target_shm_info->shm_swp);
2835 88a8c984 Riku Voipio
    __put_user(host_shm_info->swap_attempts, &target_shm_info->swap_attempts);
2836 88a8c984 Riku Voipio
    __put_user(host_shm_info->swap_successes, &target_shm_info->swap_successes);
2837 88a8c984 Riku Voipio
    unlock_user_struct(target_shm_info, target_addr, 1);
2838 88a8c984 Riku Voipio
    return 0;
2839 88a8c984 Riku Voipio
}
2840 88a8c984 Riku Voipio
2841 88a8c984 Riku Voipio
static inline abi_long do_shmctl(int shmid, int cmd, abi_long buf)
2842 88a8c984 Riku Voipio
{
2843 88a8c984 Riku Voipio
    struct shmid_ds dsarg;
2844 88a8c984 Riku Voipio
    struct shminfo shminfo;
2845 88a8c984 Riku Voipio
    struct shm_info shm_info;
2846 88a8c984 Riku Voipio
    abi_long ret = -TARGET_EINVAL;
2847 88a8c984 Riku Voipio
2848 88a8c984 Riku Voipio
    cmd &= 0xff;
2849 88a8c984 Riku Voipio
2850 88a8c984 Riku Voipio
    switch(cmd) {
2851 88a8c984 Riku Voipio
    case IPC_STAT:
2852 88a8c984 Riku Voipio
    case IPC_SET:
2853 88a8c984 Riku Voipio
    case SHM_STAT:
2854 88a8c984 Riku Voipio
        if (target_to_host_shmid_ds(&dsarg, buf))
2855 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2856 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, &dsarg));
2857 88a8c984 Riku Voipio
        if (host_to_target_shmid_ds(buf, &dsarg))
2858 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2859 88a8c984 Riku Voipio
        break;
2860 88a8c984 Riku Voipio
    case IPC_INFO:
2861 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shminfo));
2862 88a8c984 Riku Voipio
        if (host_to_target_shminfo(buf, &shminfo))
2863 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2864 88a8c984 Riku Voipio
        break;
2865 88a8c984 Riku Voipio
    case SHM_INFO:
2866 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, (struct shmid_ds *)&shm_info));
2867 88a8c984 Riku Voipio
        if (host_to_target_shm_info(buf, &shm_info))
2868 88a8c984 Riku Voipio
            return -TARGET_EFAULT;
2869 88a8c984 Riku Voipio
        break;
2870 88a8c984 Riku Voipio
    case IPC_RMID:
2871 88a8c984 Riku Voipio
    case SHM_LOCK:
2872 88a8c984 Riku Voipio
    case SHM_UNLOCK:
2873 88a8c984 Riku Voipio
        ret = get_errno(shmctl(shmid, cmd, NULL));
2874 88a8c984 Riku Voipio
        break;
2875 88a8c984 Riku Voipio
    }
2876 88a8c984 Riku Voipio
2877 88a8c984 Riku Voipio
    return ret;
2878 88a8c984 Riku Voipio
}
2879 88a8c984 Riku Voipio
2880 88a8c984 Riku Voipio
static inline abi_ulong do_shmat(int shmid, abi_ulong shmaddr, int shmflg)
2881 88a8c984 Riku Voipio
{
2882 88a8c984 Riku Voipio
    abi_long raddr;
2883 88a8c984 Riku Voipio
    void *host_raddr;
2884 88a8c984 Riku Voipio
    struct shmid_ds shm_info;
2885 88a8c984 Riku Voipio
    int i,ret;
2886 88a8c984 Riku Voipio
2887 88a8c984 Riku Voipio
    /* find out the length of the shared memory segment */
2888 88a8c984 Riku Voipio
    ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info));
2889 88a8c984 Riku Voipio
    if (is_error(ret)) {
2890 88a8c984 Riku Voipio
        /* can't get length, bail out */
2891 88a8c984 Riku Voipio
        return ret;
2892 88a8c984 Riku Voipio
    }
2893 88a8c984 Riku Voipio
2894 88a8c984 Riku Voipio
    mmap_lock();
2895 88a8c984 Riku Voipio
2896 88a8c984 Riku Voipio
    if (shmaddr)
2897 88a8c984 Riku Voipio
        host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg);
2898 88a8c984 Riku Voipio
    else {
2899 88a8c984 Riku Voipio
        abi_ulong mmap_start;
2900 88a8c984 Riku Voipio
2901 88a8c984 Riku Voipio
        mmap_start = mmap_find_vma(0, shm_info.shm_segsz);
2902 88a8c984 Riku Voipio
2903 88a8c984 Riku Voipio
        if (mmap_start == -1) {
2904 88a8c984 Riku Voipio
            errno = ENOMEM;
2905 88a8c984 Riku Voipio
            host_raddr = (void *)-1;
2906 88a8c984 Riku Voipio
        } else
2907 88a8c984 Riku Voipio
            host_raddr = shmat(shmid, g2h(mmap_start), shmflg | SHM_REMAP);
2908 88a8c984 Riku Voipio
    }
2909 88a8c984 Riku Voipio
2910 88a8c984 Riku Voipio
    if (host_raddr == (void *)-1) {
2911 88a8c984 Riku Voipio
        mmap_unlock();
2912 88a8c984 Riku Voipio
        return get_errno((long)host_raddr);
2913 88a8c984 Riku Voipio
    }
2914 88a8c984 Riku Voipio
    raddr=h2g((unsigned long)host_raddr);
2915 88a8c984 Riku Voipio
2916 88a8c984 Riku Voipio
    page_set_flags(raddr, raddr + shm_info.shm_segsz,
2917 88a8c984 Riku Voipio
                   PAGE_VALID | PAGE_READ |
2918 88a8c984 Riku Voipio
                   ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE));
2919 88a8c984 Riku Voipio
2920 88a8c984 Riku Voipio
    for (i = 0; i < N_SHM_REGIONS; i++) {
2921 88a8c984 Riku Voipio
        if (shm_regions[i].start == 0) {
2922 88a8c984 Riku Voipio
            shm_regions[i].start = raddr;
2923 88a8c984 Riku Voipio
            shm_regions[i].size = shm_info.shm_segsz;
2924 88a8c984 Riku Voipio
            break;
2925 88a8c984 Riku Voipio
        }
2926 88a8c984 Riku Voipio
    }
2927 88a8c984 Riku Voipio
2928 88a8c984 Riku Voipio
    mmap_unlock();
2929 88a8c984 Riku Voipio
    return raddr;
2930 88a8c984 Riku Voipio
2931 88a8c984 Riku Voipio
}
2932 88a8c984 Riku Voipio
2933 88a8c984 Riku Voipio
static inline abi_long do_shmdt(abi_ulong shmaddr)
2934 88a8c984 Riku Voipio
{
2935 88a8c984 Riku Voipio
    int i;
2936 88a8c984 Riku Voipio
2937 88a8c984 Riku Voipio
    for (i = 0; i < N_SHM_REGIONS; ++i) {
2938 88a8c984 Riku Voipio
        if (shm_regions[i].start == shmaddr) {
2939 88a8c984 Riku Voipio
            shm_regions[i].start = 0;
2940 e00ac249 takasi-y@ops.dti.ne.jp
            page_set_flags(shmaddr, shmaddr + shm_regions[i].size, 0);
2941 88a8c984 Riku Voipio
            break;
2942 88a8c984 Riku Voipio
        }
2943 88a8c984 Riku Voipio
    }
2944 88a8c984 Riku Voipio
2945 88a8c984 Riku Voipio
    return get_errno(shmdt(g2h(shmaddr)));
2946 88a8c984 Riku Voipio
}
2947 88a8c984 Riku Voipio
2948 1c54ff97 aurel32
#ifdef TARGET_NR_ipc
2949 53a5960a pbrook
/* ??? This only works with linear mappings.  */
2950 0da46a6e ths
/* do_ipc() must return target values and target errnos. */
2951 992f48a0 blueswir1
static abi_long do_ipc(unsigned int call, int first,
2952 992f48a0 blueswir1
                       int second, int third,
2953 992f48a0 blueswir1
                       abi_long ptr, abi_long fifth)
2954 8853f86e bellard
{
2955 8853f86e bellard
    int version;
2956 992f48a0 blueswir1
    abi_long ret = 0;
2957 8853f86e bellard
2958 8853f86e bellard
    version = call >> 16;
2959 8853f86e bellard
    call &= 0xffff;
2960 8853f86e bellard
2961 8853f86e bellard
    switch (call) {
2962 fa294816 ths
    case IPCOP_semop:
2963 e5289087 aurel32
        ret = do_semop(first, ptr, second);
2964 fa294816 ths
        break;
2965 fa294816 ths
2966 fa294816 ths
    case IPCOP_semget:
2967 fa294816 ths
        ret = get_errno(semget(first, second, third));
2968 fa294816 ths
        break;
2969 fa294816 ths
2970 fa294816 ths
    case IPCOP_semctl:
2971 e5289087 aurel32
        ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
2972 fa294816 ths
        break;
2973 d96372ef ths
2974 1c54ff97 aurel32
    case IPCOP_msgget:
2975 1c54ff97 aurel32
        ret = get_errno(msgget(first, second));
2976 1c54ff97 aurel32
        break;
2977 d96372ef ths
2978 1c54ff97 aurel32
    case IPCOP_msgsnd:
2979 1c54ff97 aurel32
        ret = do_msgsnd(first, ptr, second, third);
2980 1c54ff97 aurel32
        break;
2981 d96372ef ths
2982 1c54ff97 aurel32
    case IPCOP_msgctl:
2983 1c54ff97 aurel32
        ret = do_msgctl(first, second, ptr);
2984 1c54ff97 aurel32
        break;
2985 d96372ef ths
2986 1c54ff97 aurel32
    case IPCOP_msgrcv:
2987 1c54ff97 aurel32
        switch (version) {
2988 1c54ff97 aurel32
        case 0:
2989 1c54ff97 aurel32
            {
2990 1c54ff97 aurel32
                struct target_ipc_kludge {
2991 1c54ff97 aurel32
                    abi_long msgp;
2992 1c54ff97 aurel32
                    abi_long msgtyp;
2993 1c54ff97 aurel32
                } *tmp;
2994 1c54ff97 aurel32
2995 1c54ff97 aurel32
                if (!lock_user_struct(VERIFY_READ, tmp, ptr, 1)) {
2996 1c54ff97 aurel32
                    ret = -TARGET_EFAULT;
2997 1c54ff97 aurel32
                    break;
2998 1c54ff97 aurel32
                }
2999 d96372ef ths
3000 1c54ff97 aurel32
                ret = do_msgrcv(first, tmp->msgp, second, tmp->msgtyp, third);
3001 d96372ef ths
3002 1c54ff97 aurel32
                unlock_user_struct(tmp, ptr, 0);
3003 1c54ff97 aurel32
                break;
3004 1c54ff97 aurel32
            }
3005 1c54ff97 aurel32
        default:
3006 1c54ff97 aurel32
            ret = do_msgrcv(first, ptr, second, fifth, third);
3007 1c54ff97 aurel32
        }
3008 1c54ff97 aurel32
        break;
3009 d96372ef ths
3010 8853f86e bellard
    case IPCOP_shmat:
3011 88a8c984 Riku Voipio
        switch (version) {
3012 88a8c984 Riku Voipio
        default:
3013 5a4a898d bellard
        {
3014 5a4a898d bellard
            abi_ulong raddr;
3015 88a8c984 Riku Voipio
            raddr = do_shmat(first, ptr, second);
3016 88a8c984 Riku Voipio
            if (is_error(raddr))
3017 88a8c984 Riku Voipio
                return get_errno(raddr);
3018 2f619698 bellard
            if (put_user_ual(raddr, third))
3019 5a4a898d bellard
                return -TARGET_EFAULT;
3020 88a8c984 Riku Voipio
            break;
3021 88a8c984 Riku Voipio
        }
3022 88a8c984 Riku Voipio
        case 1:
3023 88a8c984 Riku Voipio
            ret = -TARGET_EINVAL;
3024 88a8c984 Riku Voipio
            break;
3025 5a4a898d bellard
        }
3026 8853f86e bellard
        break;
3027 8853f86e bellard
    case IPCOP_shmdt:
3028 88a8c984 Riku Voipio
        ret = do_shmdt(ptr);
3029 8853f86e bellard
        break;
3030 8853f86e bellard
3031 8853f86e bellard
    case IPCOP_shmget:
3032 8853f86e bellard
        /* IPC_* flag values are the same on all linux platforms */
3033 8853f86e bellard
        ret = get_errno(shmget(first, second, third));
3034 8853f86e bellard
        break;
3035 8853f86e bellard
3036 8853f86e bellard
        /* IPC_* and SHM_* command values are the same on all linux platforms */
3037 8853f86e bellard
    case IPCOP_shmctl:
3038 88a8c984 Riku Voipio
        ret = do_shmctl(first, second, third);
3039 8853f86e bellard
        break;
3040 8853f86e bellard
    default:
3041 32407103 j_mayer
        gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
3042 0da46a6e ths
        ret = -TARGET_ENOSYS;
3043 8853f86e bellard
        break;
3044 8853f86e bellard
    }
3045 8853f86e bellard
    return ret;
3046 8853f86e bellard
}
3047 32407103 j_mayer
#endif
3048 8853f86e bellard
3049 31e31b8a bellard
/* kernel structure types definitions */
3050 31e31b8a bellard
3051 001faf32 Blue Swirl
#define STRUCT(name, ...) STRUCT_ ## name,
3052 31e31b8a bellard
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
3053 31e31b8a bellard
enum {
3054 31e31b8a bellard
#include "syscall_types.h"
3055 31e31b8a bellard
};
3056 31e31b8a bellard
#undef STRUCT
3057 31e31b8a bellard
#undef STRUCT_SPECIAL
3058 31e31b8a bellard
3059 001faf32 Blue Swirl
#define STRUCT(name, ...) static const argtype struct_ ## name ## _def[] = {  __VA_ARGS__, TYPE_NULL };
3060 31e31b8a bellard
#define STRUCT_SPECIAL(name)
3061 31e31b8a bellard
#include "syscall_types.h"
3062 31e31b8a bellard
#undef STRUCT
3063 31e31b8a bellard
#undef STRUCT_SPECIAL
3064 31e31b8a bellard
3065 d2ef05bb Peter Maydell
typedef struct IOCTLEntry IOCTLEntry;
3066 d2ef05bb Peter Maydell
3067 d2ef05bb Peter Maydell
typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp,
3068 d2ef05bb Peter Maydell
                             int fd, abi_long cmd, abi_long arg);
3069 d2ef05bb Peter Maydell
3070 d2ef05bb Peter Maydell
struct IOCTLEntry {
3071 2ab83ea7 bellard
    unsigned int target_cmd;
3072 2ab83ea7 bellard
    unsigned int host_cmd;
3073 31e31b8a bellard
    const char *name;
3074 31e31b8a bellard
    int access;
3075 d2ef05bb Peter Maydell
    do_ioctl_fn *do_ioctl;
3076 1a9353d2 bellard
    const argtype arg_type[5];
3077 d2ef05bb Peter Maydell
};
3078 31e31b8a bellard
3079 31e31b8a bellard
#define IOC_R 0x0001
3080 31e31b8a bellard
#define IOC_W 0x0002
3081 31e31b8a bellard
#define IOC_RW (IOC_R | IOC_W)
3082 31e31b8a bellard
3083 31e31b8a bellard
#define MAX_STRUCT_SIZE 4096
3084 31e31b8a bellard
3085 dace20dc Peter Maydell
#ifdef CONFIG_FIEMAP
3086 285da2b9 Peter Maydell
/* So fiemap access checks don't overflow on 32 bit systems.
3087 285da2b9 Peter Maydell
 * This is very slightly smaller than the limit imposed by
3088 285da2b9 Peter Maydell
 * the underlying kernel.
3089 285da2b9 Peter Maydell
 */
3090 285da2b9 Peter Maydell
#define FIEMAP_MAX_EXTENTS ((UINT_MAX - sizeof(struct fiemap))  \
3091 285da2b9 Peter Maydell
                            / sizeof(struct fiemap_extent))
3092 285da2b9 Peter Maydell
3093 285da2b9 Peter Maydell
static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
3094 285da2b9 Peter Maydell
                                       int fd, abi_long cmd, abi_long arg)
3095 285da2b9 Peter Maydell
{
3096 285da2b9 Peter Maydell
    /* The parameter for this ioctl is a struct fiemap followed
3097 285da2b9 Peter Maydell
     * by an array of struct fiemap_extent whose size is set
3098 285da2b9 Peter Maydell
     * in fiemap->fm_extent_count. The array is filled in by the
3099 285da2b9 Peter Maydell
     * ioctl.
3100 285da2b9 Peter Maydell
     */
3101 285da2b9 Peter Maydell
    int target_size_in, target_size_out;
3102 285da2b9 Peter Maydell
    struct fiemap *fm;
3103 285da2b9 Peter Maydell
    const argtype *arg_type = ie->arg_type;
3104 285da2b9 Peter Maydell
    const argtype extent_arg_type[] = { MK_STRUCT(STRUCT_fiemap_extent) };
3105 285da2b9 Peter Maydell
    void *argptr, *p;
3106 285da2b9 Peter Maydell
    abi_long ret;
3107 285da2b9 Peter Maydell
    int i, extent_size = thunk_type_size(extent_arg_type, 0);
3108 285da2b9 Peter Maydell
    uint32_t outbufsz;
3109 285da2b9 Peter Maydell
    int free_fm = 0;
3110 285da2b9 Peter Maydell
3111 285da2b9 Peter Maydell
    assert(arg_type[0] == TYPE_PTR);
3112 285da2b9 Peter Maydell
    assert(ie->access == IOC_RW);
3113 285da2b9 Peter Maydell
    arg_type++;
3114 285da2b9 Peter Maydell
    target_size_in = thunk_type_size(arg_type, 0);
3115 285da2b9 Peter Maydell
    argptr = lock_user(VERIFY_READ, arg, target_size_in, 1);
3116 285da2b9 Peter Maydell
    if (!argptr) {
3117 285da2b9 Peter Maydell
        return -TARGET_EFAULT;
3118 285da2b9 Peter Maydell
    }
3119 285da2b9 Peter Maydell
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3120 285da2b9 Peter Maydell
    unlock_user(argptr, arg, 0);
3121 285da2b9 Peter Maydell
    fm = (struct fiemap *)buf_temp;
3122 285da2b9 Peter Maydell
    if (fm->fm_extent_count > FIEMAP_MAX_EXTENTS) {
3123 285da2b9 Peter Maydell
        return -TARGET_EINVAL;
3124 285da2b9 Peter Maydell
    }
3125 285da2b9 Peter Maydell
3126 285da2b9 Peter Maydell
    outbufsz = sizeof (*fm) +
3127 285da2b9 Peter Maydell
        (sizeof(struct fiemap_extent) * fm->fm_extent_count);
3128 285da2b9 Peter Maydell
3129 285da2b9 Peter Maydell
    if (outbufsz > MAX_STRUCT_SIZE) {
3130 285da2b9 Peter Maydell
        /* We can't fit all the extents into the fixed size buffer.
3131 285da2b9 Peter Maydell
         * Allocate one that is large enough and use it instead.
3132 285da2b9 Peter Maydell
         */
3133 285da2b9 Peter Maydell
        fm = malloc(outbufsz);
3134 285da2b9 Peter Maydell
        if (!fm) {
3135 285da2b9 Peter Maydell
            return -TARGET_ENOMEM;
3136 285da2b9 Peter Maydell
        }
3137 285da2b9 Peter Maydell
        memcpy(fm, buf_temp, sizeof(struct fiemap));
3138 285da2b9 Peter Maydell
        free_fm = 1;
3139 285da2b9 Peter Maydell
    }
3140 285da2b9 Peter Maydell
    ret = get_errno(ioctl(fd, ie->host_cmd, fm));
3141 285da2b9 Peter Maydell
    if (!is_error(ret)) {
3142 285da2b9 Peter Maydell
        target_size_out = target_size_in;
3143 285da2b9 Peter Maydell
        /* An extent_count of 0 means we were only counting the extents
3144 285da2b9 Peter Maydell
         * so there are no structs to copy
3145 285da2b9 Peter Maydell
         */
3146 285da2b9 Peter Maydell
        if (fm->fm_extent_count != 0) {
3147 285da2b9 Peter Maydell
            target_size_out += fm->fm_mapped_extents * extent_size;
3148 285da2b9 Peter Maydell
        }
3149 285da2b9 Peter Maydell
        argptr = lock_user(VERIFY_WRITE, arg, target_size_out, 0);
3150 285da2b9 Peter Maydell
        if (!argptr) {
3151 285da2b9 Peter Maydell
            ret = -TARGET_EFAULT;
3152 285da2b9 Peter Maydell
        } else {
3153 285da2b9 Peter Maydell
            /* Convert the struct fiemap */
3154 285da2b9 Peter Maydell
            thunk_convert(argptr, fm, arg_type, THUNK_TARGET);
3155 285da2b9 Peter Maydell
            if (fm->fm_extent_count != 0) {
3156 285da2b9 Peter Maydell
                p = argptr + target_size_in;
3157 285da2b9 Peter Maydell
                /* ...and then all the struct fiemap_extents */
3158 285da2b9 Peter Maydell
                for (i = 0; i < fm->fm_mapped_extents; i++) {
3159 285da2b9 Peter Maydell
                    thunk_convert(p, &fm->fm_extents[i], extent_arg_type,
3160 285da2b9 Peter Maydell
                                  THUNK_TARGET);
3161 285da2b9 Peter Maydell
                    p += extent_size;
3162 285da2b9 Peter Maydell
                }
3163 285da2b9 Peter Maydell
            }
3164 285da2b9 Peter Maydell
            unlock_user(argptr, arg, target_size_out);
3165 285da2b9 Peter Maydell
        }
3166 285da2b9 Peter Maydell
    }
3167 285da2b9 Peter Maydell
    if (free_fm) {
3168 285da2b9 Peter Maydell
        free(fm);
3169 285da2b9 Peter Maydell
    }
3170 285da2b9 Peter Maydell
    return ret;
3171 285da2b9 Peter Maydell
}
3172 dace20dc Peter Maydell
#endif
3173 285da2b9 Peter Maydell
3174 059c2f2c Laurent Vivier
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
3175 059c2f2c Laurent Vivier
                                int fd, abi_long cmd, abi_long arg)
3176 059c2f2c Laurent Vivier
{
3177 059c2f2c Laurent Vivier
    const argtype *arg_type = ie->arg_type;
3178 059c2f2c Laurent Vivier
    int target_size;
3179 059c2f2c Laurent Vivier
    void *argptr;
3180 059c2f2c Laurent Vivier
    int ret;
3181 059c2f2c Laurent Vivier
    struct ifconf *host_ifconf;
3182 059c2f2c Laurent Vivier
    uint32_t outbufsz;
3183 059c2f2c Laurent Vivier
    const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
3184 059c2f2c Laurent Vivier
    int target_ifreq_size;
3185 059c2f2c Laurent Vivier
    int nb_ifreq;
3186 059c2f2c Laurent Vivier
    int free_buf = 0;
3187 059c2f2c Laurent Vivier
    int i;
3188 059c2f2c Laurent Vivier
    int target_ifc_len;
3189 059c2f2c Laurent Vivier
    abi_long target_ifc_buf;
3190 059c2f2c Laurent Vivier
    int host_ifc_len;
3191 059c2f2c Laurent Vivier
    char *host_ifc_buf;
3192 059c2f2c Laurent Vivier
3193 059c2f2c Laurent Vivier
    assert(arg_type[0] == TYPE_PTR);
3194 059c2f2c Laurent Vivier
    assert(ie->access == IOC_RW);
3195 059c2f2c Laurent Vivier
3196 059c2f2c Laurent Vivier
    arg_type++;
3197 059c2f2c Laurent Vivier
    target_size = thunk_type_size(arg_type, 0);
3198 059c2f2c Laurent Vivier
3199 059c2f2c Laurent Vivier
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3200 059c2f2c Laurent Vivier
    if (!argptr)
3201 059c2f2c Laurent Vivier
        return -TARGET_EFAULT;
3202 059c2f2c Laurent Vivier
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3203 059c2f2c Laurent Vivier
    unlock_user(argptr, arg, 0);
3204 059c2f2c Laurent Vivier
3205 059c2f2c Laurent Vivier
    host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
3206 059c2f2c Laurent Vivier
    target_ifc_len = host_ifconf->ifc_len;
3207 059c2f2c Laurent Vivier
    target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
3208 059c2f2c Laurent Vivier
3209 059c2f2c Laurent Vivier
    target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
3210 059c2f2c Laurent Vivier
    nb_ifreq = target_ifc_len / target_ifreq_size;
3211 059c2f2c Laurent Vivier
    host_ifc_len = nb_ifreq * sizeof(struct ifreq);
3212 059c2f2c Laurent Vivier
3213 059c2f2c Laurent Vivier
    outbufsz = sizeof(*host_ifconf) + host_ifc_len;
3214 059c2f2c Laurent Vivier
    if (outbufsz > MAX_STRUCT_SIZE) {
3215 059c2f2c Laurent Vivier
        /* We can't fit all the extents into the fixed size buffer.
3216 059c2f2c Laurent Vivier
         * Allocate one that is large enough and use it instead.
3217 059c2f2c Laurent Vivier
         */
3218 059c2f2c Laurent Vivier
        host_ifconf = malloc(outbufsz);
3219 059c2f2c Laurent Vivier
        if (!host_ifconf) {
3220 059c2f2c Laurent Vivier
            return -TARGET_ENOMEM;
3221 059c2f2c Laurent Vivier
        }
3222 059c2f2c Laurent Vivier
        memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
3223 059c2f2c Laurent Vivier
        free_buf = 1;
3224 059c2f2c Laurent Vivier
    }
3225 059c2f2c Laurent Vivier
    host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
3226 059c2f2c Laurent Vivier
3227 059c2f2c Laurent Vivier
    host_ifconf->ifc_len = host_ifc_len;
3228 059c2f2c Laurent Vivier
    host_ifconf->ifc_buf = host_ifc_buf;
3229 059c2f2c Laurent Vivier
3230 059c2f2c Laurent Vivier
    ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
3231 059c2f2c Laurent Vivier
    if (!is_error(ret)) {
3232 059c2f2c Laurent Vivier
        /* convert host ifc_len to target ifc_len */
3233 059c2f2c Laurent Vivier
3234 059c2f2c Laurent Vivier
        nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
3235 059c2f2c Laurent Vivier
        target_ifc_len = nb_ifreq * target_ifreq_size;
3236 059c2f2c Laurent Vivier
        host_ifconf->ifc_len = target_ifc_len;
3237 059c2f2c Laurent Vivier
3238 059c2f2c Laurent Vivier
        /* restore target ifc_buf */
3239 059c2f2c Laurent Vivier
3240 059c2f2c Laurent Vivier
        host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
3241 059c2f2c Laurent Vivier
3242 059c2f2c Laurent Vivier
        /* copy struct ifconf to target user */
3243 059c2f2c Laurent Vivier
3244 059c2f2c Laurent Vivier
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3245 059c2f2c Laurent Vivier
        if (!argptr)
3246 059c2f2c Laurent Vivier
            return -TARGET_EFAULT;
3247 059c2f2c Laurent Vivier
        thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
3248 059c2f2c Laurent Vivier
        unlock_user(argptr, arg, target_size);
3249 059c2f2c Laurent Vivier
3250 059c2f2c Laurent Vivier
        /* copy ifreq[] to target user */
3251 059c2f2c Laurent Vivier
3252 059c2f2c Laurent Vivier
        argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
3253 059c2f2c Laurent Vivier
        for (i = 0; i < nb_ifreq ; i++) {
3254 059c2f2c Laurent Vivier
            thunk_convert(argptr + i * target_ifreq_size,
3255 059c2f2c Laurent Vivier
                          host_ifc_buf + i * sizeof(struct ifreq),
3256 059c2f2c Laurent Vivier
                          ifreq_arg_type, THUNK_TARGET);
3257 059c2f2c Laurent Vivier
        }
3258 059c2f2c Laurent Vivier
        unlock_user(argptr, target_ifc_buf, target_ifc_len);
3259 059c2f2c Laurent Vivier
    }
3260 059c2f2c Laurent Vivier
3261 059c2f2c Laurent Vivier
    if (free_buf) {
3262 059c2f2c Laurent Vivier
        free(host_ifconf);
3263 059c2f2c Laurent Vivier
    }
3264 059c2f2c Laurent Vivier
3265 059c2f2c Laurent Vivier
    return ret;
3266 059c2f2c Laurent Vivier
}
3267 059c2f2c Laurent Vivier
3268 9f106a75 blueswir1
static IOCTLEntry ioctl_entries[] = {
3269 001faf32 Blue Swirl
#define IOCTL(cmd, access, ...) \
3270 d2ef05bb Peter Maydell
    { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
3271 d2ef05bb Peter Maydell
#define IOCTL_SPECIAL(cmd, access, dofn, ...)                      \
3272 d2ef05bb Peter Maydell
    { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
3273 31e31b8a bellard
#include "ioctls.h"
3274 31e31b8a bellard
    { 0, 0, },
3275 31e31b8a bellard
};
3276 31e31b8a bellard
3277 53a5960a pbrook
/* ??? Implement proper locking for ioctls.  */
3278 0da46a6e ths
/* do_ioctl() Must return target values and target errnos. */
3279 992f48a0 blueswir1
static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
3280 31e31b8a bellard
{
3281 31e31b8a bellard
    const IOCTLEntry *ie;
3282 31e31b8a bellard
    const argtype *arg_type;
3283 992f48a0 blueswir1
    abi_long ret;
3284 31e31b8a bellard
    uint8_t buf_temp[MAX_STRUCT_SIZE];
3285 53a5960a pbrook
    int target_size;
3286 53a5960a pbrook
    void *argptr;
3287 31e31b8a bellard
3288 31e31b8a bellard
    ie = ioctl_entries;
3289 31e31b8a bellard
    for(;;) {
3290 31e31b8a bellard
        if (ie->target_cmd == 0) {
3291 32407103 j_mayer
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
3292 0da46a6e ths
            return -TARGET_ENOSYS;
3293 31e31b8a bellard
        }
3294 31e31b8a bellard
        if (ie->target_cmd == cmd)
3295 31e31b8a bellard
            break;
3296 31e31b8a bellard
        ie++;
3297 31e31b8a bellard
    }
3298 31e31b8a bellard
    arg_type = ie->arg_type;
3299 9de5e440 bellard
#if defined(DEBUG)
3300 32407103 j_mayer
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name);
3301 72f03900 bellard
#endif
3302 d2ef05bb Peter Maydell
    if (ie->do_ioctl) {
3303 d2ef05bb Peter Maydell
        return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
3304 d2ef05bb Peter Maydell
    }
3305 d2ef05bb Peter Maydell
3306 31e31b8a bellard
    switch(arg_type[0]) {
3307 31e31b8a bellard
    case TYPE_NULL:
3308 31e31b8a bellard
        /* no argument */
3309 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd));
3310 31e31b8a bellard
        break;
3311 31e31b8a bellard
    case TYPE_PTRVOID:
3312 31e31b8a bellard
    case TYPE_INT:
3313 31e31b8a bellard
        /* int argment */
3314 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
3315 31e31b8a bellard
        break;
3316 31e31b8a bellard
    case TYPE_PTR:
3317 31e31b8a bellard
        arg_type++;
3318 53a5960a pbrook
        target_size = thunk_type_size(arg_type, 0);
3319 31e31b8a bellard
        switch(ie->access) {
3320 31e31b8a bellard
        case IOC_R:
3321 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3322 31e31b8a bellard
            if (!is_error(ret)) {
3323 579a97f7 bellard
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3324 579a97f7 bellard
                if (!argptr)
3325 579a97f7 bellard
                    return -TARGET_EFAULT;
3326 53a5960a pbrook
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3327 53a5960a pbrook
                unlock_user(argptr, arg, target_size);
3328 31e31b8a bellard
            }
3329 31e31b8a bellard
            break;
3330 31e31b8a bellard
        case IOC_W:
3331 579a97f7 bellard
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3332 579a97f7 bellard
            if (!argptr)
3333 579a97f7 bellard
                return -TARGET_EFAULT;
3334 53a5960a pbrook
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3335 53a5960a pbrook
            unlock_user(argptr, arg, 0);
3336 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3337 31e31b8a bellard
            break;
3338 31e31b8a bellard
        default:
3339 31e31b8a bellard
        case IOC_RW:
3340 579a97f7 bellard
            argptr = lock_user(VERIFY_READ, arg, target_size, 1);
3341 579a97f7 bellard
            if (!argptr)
3342 579a97f7 bellard
                return -TARGET_EFAULT;
3343 53a5960a pbrook
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
3344 53a5960a pbrook
            unlock_user(argptr, arg, 0);
3345 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
3346 31e31b8a bellard
            if (!is_error(ret)) {
3347 579a97f7 bellard
                argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
3348 579a97f7 bellard
                if (!argptr)
3349 579a97f7 bellard
                    return -TARGET_EFAULT;
3350 53a5960a pbrook
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
3351 53a5960a pbrook
                unlock_user(argptr, arg, target_size);
3352 31e31b8a bellard
            }
3353 31e31b8a bellard
            break;
3354 31e31b8a bellard
        }
3355 31e31b8a bellard
        break;
3356 31e31b8a bellard
    default:
3357 32407103 j_mayer
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n",
3358 32407103 j_mayer
                 (long)cmd, arg_type[0]);
3359 0da46a6e ths
        ret = -TARGET_ENOSYS;
3360 31e31b8a bellard
        break;
3361 31e31b8a bellard
    }
3362 31e31b8a bellard
    return ret;
3363 31e31b8a bellard
}
3364 31e31b8a bellard
3365 b39bc503 blueswir1
static const bitmask_transtbl iflag_tbl[] = {
3366 31e31b8a bellard
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
3367 31e31b8a bellard
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
3368 31e31b8a bellard
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
3369 31e31b8a bellard
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
3370 31e31b8a bellard
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
3371 31e31b8a bellard
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
3372 31e31b8a bellard
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
3373 31e31b8a bellard
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
3374 31e31b8a bellard
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
3375 31e31b8a bellard
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
3376 31e31b8a bellard
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
3377 31e31b8a bellard
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
3378 31e31b8a bellard
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
3379 31e31b8a bellard
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
3380 31e31b8a bellard
        { 0, 0, 0, 0 }
3381 31e31b8a bellard
};
3382 31e31b8a bellard
3383 b39bc503 blueswir1
static const bitmask_transtbl oflag_tbl[] = {
3384 31e31b8a bellard
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
3385 31e31b8a bellard
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
3386 31e31b8a bellard
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
3387 31e31b8a bellard
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
3388 31e31b8a bellard
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
3389 31e31b8a bellard
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
3390 31e31b8a bellard
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
3391 31e31b8a bellard
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
3392 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
3393 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
3394 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
3395 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
3396 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
3397 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
3398 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
3399 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
3400 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
3401 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
3402 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
3403 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
3404 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
3405 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
3406 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
3407 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
3408 31e31b8a bellard
        { 0, 0, 0, 0 }
3409 31e31b8a bellard
};
3410 31e31b8a bellard
3411 b39bc503 blueswir1
static const bitmask_transtbl cflag_tbl[] = {
3412 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
3413 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
3414 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
3415 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
3416 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
3417 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
3418 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
3419 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
3420 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
3421 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
3422 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
3423 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
3424 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
3425 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
3426 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
3427 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
3428 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
3429 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
3430 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
3431 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
3432 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
3433 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
3434 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
3435 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
3436 31e31b8a bellard
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
3437 31e31b8a bellard
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
3438 31e31b8a bellard
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
3439 31e31b8a bellard
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
3440 31e31b8a bellard
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
3441 31e31b8a bellard
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
3442 31e31b8a bellard
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
3443 31e31b8a bellard
        { 0, 0, 0, 0 }
3444 31e31b8a bellard
};
3445 31e31b8a bellard
3446 b39bc503 blueswir1
static const bitmask_transtbl lflag_tbl[] = {
3447 31e31b8a bellard
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
3448 31e31b8a bellard
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
3449 31e31b8a bellard
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
3450 31e31b8a bellard
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
3451 31e31b8a bellard
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
3452 31e31b8a bellard
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
3453 31e31b8a bellard
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
3454 31e31b8a bellard
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
3455 31e31b8a bellard
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
3456 31e31b8a bellard
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
3457 31e31b8a bellard
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
3458 31e31b8a bellard
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
3459 31e31b8a bellard
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
3460 31e31b8a bellard
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
3461 31e31b8a bellard
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
3462 31e31b8a bellard
        { 0, 0, 0, 0 }
3463 31e31b8a bellard
};
3464 31e31b8a bellard
3465 31e31b8a bellard
static void target_to_host_termios (void *dst, const void *src)
3466 31e31b8a bellard
{
3467 31e31b8a bellard
    struct host_termios *host = dst;
3468 31e31b8a bellard
    const struct target_termios *target = src;
3469 3b46e624 ths
3470 5fafdf24 ths
    host->c_iflag =
3471 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
3472 5fafdf24 ths
    host->c_oflag =
3473 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
3474 5fafdf24 ths
    host->c_cflag =
3475 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
3476 5fafdf24 ths
    host->c_lflag =
3477 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
3478 31e31b8a bellard
    host->c_line = target->c_line;
3479 3b46e624 ths
3480 44607123 Arnaud Patard
    memset(host->c_cc, 0, sizeof(host->c_cc));
3481 5fafdf24 ths
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR];
3482 5fafdf24 ths
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT];
3483 3b46e624 ths
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];
3484 5fafdf24 ths
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL];
3485 3b46e624 ths
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];
3486 5fafdf24 ths
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME];
3487 3b46e624 ths
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];
3488 5fafdf24 ths
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC];
3489 3b46e624 ths
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];
3490 5fafdf24 ths
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP];
3491 5fafdf24 ths
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP];
3492 3b46e624 ths
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];
3493 3b46e624 ths
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];
3494 3b46e624 ths
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];
3495 3b46e624 ths
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];
3496 3b46e624 ths
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];
3497 5fafdf24 ths
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2];
3498 31e31b8a bellard
}
3499 3b46e624 ths
3500 31e31b8a bellard
static void host_to_target_termios (void *dst, const void *src)
3501 31e31b8a bellard
{
3502 31e31b8a bellard
    struct target_termios *target = dst;
3503 31e31b8a bellard
    const struct host_termios *host = src;
3504 31e31b8a bellard
3505 5fafdf24 ths
    target->c_iflag =
3506 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
3507 5fafdf24 ths
    target->c_oflag =
3508 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
3509 5fafdf24 ths
    target->c_cflag =
3510 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
3511 5fafdf24 ths
    target->c_lflag =
3512 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
3513 31e31b8a bellard
    target->c_line = host->c_line;
3514 3b46e624 ths
3515 44607123 Arnaud Patard
    memset(target->c_cc, 0, sizeof(target->c_cc));
3516 31e31b8a bellard
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
3517 31e31b8a bellard
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
3518 31e31b8a bellard
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
3519 31e31b8a bellard
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
3520 31e31b8a bellard
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
3521 31e31b8a bellard
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
3522 31e31b8a bellard
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
3523 31e31b8a bellard
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
3524 31e31b8a bellard
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
3525 31e31b8a bellard
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
3526 31e31b8a bellard
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
3527 31e31b8a bellard
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
3528 31e31b8a bellard
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
3529 31e31b8a bellard
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
3530 31e31b8a bellard
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
3531 31e31b8a bellard
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
3532 31e31b8a bellard
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
3533 31e31b8a bellard
}
3534 31e31b8a bellard
3535 8e853dc7 blueswir1
static const StructEntry struct_termios_def = {
3536 31e31b8a bellard
    .convert = { host_to_target_termios, target_to_host_termios },
3537 31e31b8a bellard
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
3538 31e31b8a bellard
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
3539 31e31b8a bellard
};
3540 31e31b8a bellard
3541 5286db75 bellard
static bitmask_transtbl mmap_flags_tbl[] = {
3542 5286db75 bellard
        { TARGET_MAP_SHARED, TARGET_MAP_SHARED, MAP_SHARED, MAP_SHARED },
3543 5286db75 bellard
        { TARGET_MAP_PRIVATE, TARGET_MAP_PRIVATE, MAP_PRIVATE, MAP_PRIVATE },
3544 5286db75 bellard
        { TARGET_MAP_FIXED, TARGET_MAP_FIXED, MAP_FIXED, MAP_FIXED },
3545 5286db75 bellard
        { TARGET_MAP_ANONYMOUS, TARGET_MAP_ANONYMOUS, MAP_ANONYMOUS, MAP_ANONYMOUS },
3546 5286db75 bellard
        { TARGET_MAP_GROWSDOWN, TARGET_MAP_GROWSDOWN, MAP_GROWSDOWN, MAP_GROWSDOWN },
3547 5286db75 bellard
        { TARGET_MAP_DENYWRITE, TARGET_MAP_DENYWRITE, MAP_DENYWRITE, MAP_DENYWRITE },
3548 5286db75 bellard
        { TARGET_MAP_EXECUTABLE, TARGET_MAP_EXECUTABLE, MAP_EXECUTABLE, MAP_EXECUTABLE },
3549 5286db75 bellard
        { TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
3550 5286db75 bellard
        { 0, 0, 0, 0 }
3551 5286db75 bellard
};
3552 5286db75 bellard
3553 2ab83ea7 bellard
#if defined(TARGET_I386)
3554 6dbad63e bellard
3555 6dbad63e bellard
/* NOTE: there is really one LDT for all the threads */
3556 b1d8e52e blueswir1
static uint8_t *ldt_table;
3557 6dbad63e bellard
3558 03acab66 bellard
static abi_long read_ldt(abi_ulong ptr, unsigned long bytecount)
3559 6dbad63e bellard
{
3560 6dbad63e bellard
    int size;
3561 53a5960a pbrook
    void *p;
3562 6dbad63e bellard
3563 6dbad63e bellard
    if (!ldt_table)
3564 6dbad63e bellard
        return 0;
3565 6dbad63e bellard
    size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
3566 6dbad63e bellard
    if (size > bytecount)
3567 6dbad63e bellard
        size = bytecount;
3568 579a97f7 bellard
    p = lock_user(VERIFY_WRITE, ptr, size, 0);
3569 579a97f7 bellard
    if (!p)
3570 03acab66 bellard
        return -TARGET_EFAULT;
3571 579a97f7 bellard
    /* ??? Should this by byteswapped?  */
3572 53a5960a pbrook
    memcpy(p, ldt_table, size);
3573 53a5960a pbrook
    unlock_user(p, ptr, size);
3574 6dbad63e bellard
    return size;
3575 6dbad63e bellard
}
3576 6dbad63e bellard
3577 6dbad63e bellard
/* XXX: add locking support */
3578 03acab66 bellard
static abi_long write_ldt(CPUX86State *env,
3579 03acab66 bellard
                          abi_ulong ptr, unsigned long bytecount, int oldmode)
3580 6dbad63e bellard
{
3581 6dbad63e bellard
    struct target_modify_ldt_ldt_s ldt_info;
3582 53a5960a pbrook
    struct target_modify_ldt_ldt_s *target_ldt_info;
3583 6dbad63e bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3584 8d18e893 bellard
    int seg_not_present, useable, lm;
3585 6dbad63e bellard
    uint32_t *lp, entry_1, entry_2;
3586 6dbad63e bellard
3587 6dbad63e bellard
    if (bytecount != sizeof(ldt_info))
3588 03acab66 bellard
        return -TARGET_EINVAL;
3589 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_ldt_info, ptr, 1))
3590 03acab66 bellard
        return -TARGET_EFAULT;
3591 53a5960a pbrook
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3592 53a5960a pbrook
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3593 53a5960a pbrook
    ldt_info.limit = tswap32(target_ldt_info->limit);
3594 53a5960a pbrook
    ldt_info.flags = tswap32(target_ldt_info->flags);
3595 53a5960a pbrook
    unlock_user_struct(target_ldt_info, ptr, 0);
3596 3b46e624 ths
3597 6dbad63e bellard
    if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
3598 03acab66 bellard
        return -TARGET_EINVAL;
3599 6dbad63e bellard
    seg_32bit = ldt_info.flags & 1;
3600 6dbad63e bellard
    contents = (ldt_info.flags >> 1) & 3;
3601 6dbad63e bellard
    read_exec_only = (ldt_info.flags >> 3) & 1;
3602 6dbad63e bellard
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3603 6dbad63e bellard
    seg_not_present = (ldt_info.flags >> 5) & 1;
3604 6dbad63e bellard
    useable = (ldt_info.flags >> 6) & 1;
3605 8d18e893 bellard
#ifdef TARGET_ABI32
3606 8d18e893 bellard
    lm = 0;
3607 8d18e893 bellard
#else
3608 8d18e893 bellard
    lm = (ldt_info.flags >> 7) & 1;
3609 8d18e893 bellard
#endif
3610 6dbad63e bellard
    if (contents == 3) {
3611 6dbad63e bellard
        if (oldmode)
3612 03acab66 bellard
            return -TARGET_EINVAL;
3613 6dbad63e bellard
        if (seg_not_present == 0)
3614 03acab66 bellard
            return -TARGET_EINVAL;
3615 6dbad63e bellard
    }
3616 6dbad63e bellard
    /* allocate the LDT */
3617 6dbad63e bellard
    if (!ldt_table) {
3618 e441570f balrog
        env->ldt.base = target_mmap(0,
3619 e441570f balrog
                                    TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE,
3620 e441570f balrog
                                    PROT_READ|PROT_WRITE,
3621 e441570f balrog
                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
3622 e441570f balrog
        if (env->ldt.base == -1)
3623 03acab66 bellard
            return -TARGET_ENOMEM;
3624 e441570f balrog
        memset(g2h(env->ldt.base), 0,
3625 e441570f balrog
               TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
3626 6dbad63e bellard
        env->ldt.limit = 0xffff;
3627 e441570f balrog
        ldt_table = g2h(env->ldt.base);
3628 6dbad63e bellard
    }
3629 6dbad63e bellard
3630 6dbad63e bellard
    /* NOTE: same code as Linux kernel */
3631 6dbad63e bellard
    /* Allow LDTs to be cleared by the user. */
3632 6dbad63e bellard
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3633 6dbad63e bellard
        if (oldmode ||
3634 6dbad63e bellard
            (contents == 0                &&
3635 6dbad63e bellard
             read_exec_only == 1        &&
3636 6dbad63e bellard
             seg_32bit == 0                &&
3637 6dbad63e bellard
             limit_in_pages == 0        &&
3638 6dbad63e bellard
             seg_not_present == 1        &&
3639 6dbad63e bellard
             useable == 0 )) {
3640 6dbad63e bellard
            entry_1 = 0;
3641 6dbad63e bellard
            entry_2 = 0;
3642 6dbad63e bellard
            goto install;
3643 6dbad63e bellard
        }
3644 6dbad63e bellard
    }
3645 3b46e624 ths
3646 6dbad63e bellard
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3647 6dbad63e bellard
        (ldt_info.limit & 0x0ffff);
3648 6dbad63e bellard
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3649 6dbad63e bellard
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3650 6dbad63e bellard
        (ldt_info.limit & 0xf0000) |
3651 6dbad63e bellard
        ((read_exec_only ^ 1) << 9) |
3652 6dbad63e bellard
        (contents << 10) |
3653 6dbad63e bellard
        ((seg_not_present ^ 1) << 15) |
3654 6dbad63e bellard
        (seg_32bit << 22) |
3655 6dbad63e bellard
        (limit_in_pages << 23) |
3656 8d18e893 bellard
        (lm << 21) |
3657 6dbad63e bellard
        0x7000;
3658 6dbad63e bellard
    if (!oldmode)
3659 6dbad63e bellard
        entry_2 |= (useable << 20);
3660 14ae3ba7 bellard
3661 6dbad63e bellard
    /* Install the new entry ...  */
3662 6dbad63e bellard
install:
3663 6dbad63e bellard
    lp = (uint32_t *)(ldt_table + (ldt_info.entry_number << 3));
3664 6dbad63e bellard
    lp[0] = tswap32(entry_1);
3665 6dbad63e bellard
    lp[1] = tswap32(entry_2);
3666 6dbad63e bellard
    return 0;
3667 6dbad63e bellard
}
3668 6dbad63e bellard
3669 6dbad63e bellard
/* specific and weird i386 syscalls */
3670 8fcd3692 blueswir1
static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
3671 8fcd3692 blueswir1
                              unsigned long bytecount)
3672 6dbad63e bellard
{
3673 03acab66 bellard
    abi_long ret;
3674 3b46e624 ths
3675 6dbad63e bellard
    switch (func) {
3676 6dbad63e bellard
    case 0:
3677 6dbad63e bellard
        ret = read_ldt(ptr, bytecount);
3678 6dbad63e bellard
        break;
3679 6dbad63e bellard
    case 1:
3680 6dbad63e bellard
        ret = write_ldt(env, ptr, bytecount, 1);
3681 6dbad63e bellard
        break;
3682 6dbad63e bellard
    case 0x11:
3683 6dbad63e bellard
        ret = write_ldt(env, ptr, bytecount, 0);
3684 6dbad63e bellard
        break;
3685 03acab66 bellard
    default:
3686 03acab66 bellard
        ret = -TARGET_ENOSYS;
3687 03acab66 bellard
        break;
3688 6dbad63e bellard
    }
3689 6dbad63e bellard
    return ret;
3690 6dbad63e bellard
}
3691 1b6b029e bellard
3692 4583f589 blueswir1
#if defined(TARGET_I386) && defined(TARGET_ABI32)
3693 8fcd3692 blueswir1
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
3694 8d18e893 bellard
{
3695 8d18e893 bellard
    uint64_t *gdt_table = g2h(env->gdt.base);
3696 8d18e893 bellard
    struct target_modify_ldt_ldt_s ldt_info;
3697 8d18e893 bellard
    struct target_modify_ldt_ldt_s *target_ldt_info;
3698 8d18e893 bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages;
3699 8d18e893 bellard
    int seg_not_present, useable, lm;
3700 8d18e893 bellard
    uint32_t *lp, entry_1, entry_2;
3701 8d18e893 bellard
    int i;
3702 8d18e893 bellard
3703 8d18e893 bellard
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3704 8d18e893 bellard
    if (!target_ldt_info)
3705 8d18e893 bellard
        return -TARGET_EFAULT;
3706 8d18e893 bellard
    ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
3707 8d18e893 bellard
    ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
3708 8d18e893 bellard
    ldt_info.limit = tswap32(target_ldt_info->limit);
3709 8d18e893 bellard
    ldt_info.flags = tswap32(target_ldt_info->flags);
3710 8d18e893 bellard
    if (ldt_info.entry_number == -1) {
3711 8d18e893 bellard
        for (i=TARGET_GDT_ENTRY_TLS_MIN; i<=TARGET_GDT_ENTRY_TLS_MAX; i++) {
3712 8d18e893 bellard
            if (gdt_table[i] == 0) {
3713 8d18e893 bellard
                ldt_info.entry_number = i;
3714 8d18e893 bellard
                target_ldt_info->entry_number = tswap32(i);
3715 8d18e893 bellard
                break;
3716 8d18e893 bellard
            }
3717 8d18e893 bellard
        }
3718 8d18e893 bellard
    }
3719 8d18e893 bellard
    unlock_user_struct(target_ldt_info, ptr, 1);
3720 8d18e893 bellard
3721 8d18e893 bellard
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
3722 8d18e893 bellard
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
3723 8d18e893 bellard
           return -TARGET_EINVAL;
3724 8d18e893 bellard
    seg_32bit = ldt_info.flags & 1;
3725 8d18e893 bellard
    contents = (ldt_info.flags >> 1) & 3;
3726 8d18e893 bellard
    read_exec_only = (ldt_info.flags >> 3) & 1;
3727 8d18e893 bellard
    limit_in_pages = (ldt_info.flags >> 4) & 1;
3728 8d18e893 bellard
    seg_not_present = (ldt_info.flags >> 5) & 1;
3729 8d18e893 bellard
    useable = (ldt_info.flags >> 6) & 1;
3730 8d18e893 bellard
#ifdef TARGET_ABI32
3731 8d18e893 bellard
    lm = 0;
3732 8d18e893 bellard
#else
3733 8d18e893 bellard
    lm = (ldt_info.flags >> 7) & 1;
3734 8d18e893 bellard
#endif
3735 8d18e893 bellard
3736 8d18e893 bellard
    if (contents == 3) {
3737 8d18e893 bellard
        if (seg_not_present == 0)
3738 8d18e893 bellard
            return -TARGET_EINVAL;
3739 8d18e893 bellard
    }
3740 8d18e893 bellard
3741 8d18e893 bellard
    /* NOTE: same code as Linux kernel */
3742 8d18e893 bellard
    /* Allow LDTs to be cleared by the user. */
3743 8d18e893 bellard
    if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
3744 8d18e893 bellard
        if ((contents == 0             &&
3745 8d18e893 bellard
             read_exec_only == 1       &&
3746 8d18e893 bellard
             seg_32bit == 0            &&
3747 8d18e893 bellard
             limit_in_pages == 0       &&
3748 8d18e893 bellard
             seg_not_present == 1      &&
3749 8d18e893 bellard
             useable == 0 )) {
3750 8d18e893 bellard
            entry_1 = 0;
3751 8d18e893 bellard
            entry_2 = 0;
3752 8d18e893 bellard
            goto install;
3753 8d18e893 bellard
        }
3754 8d18e893 bellard
    }
3755 8d18e893 bellard
3756 8d18e893 bellard
    entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) |
3757 8d18e893 bellard
        (ldt_info.limit & 0x0ffff);
3758 8d18e893 bellard
    entry_2 = (ldt_info.base_addr & 0xff000000) |
3759 8d18e893 bellard
        ((ldt_info.base_addr & 0x00ff0000) >> 16) |
3760 8d18e893 bellard
        (ldt_info.limit & 0xf0000) |
3761 8d18e893 bellard
        ((read_exec_only ^ 1) << 9) |
3762 8d18e893 bellard
        (contents << 10) |
3763 8d18e893 bellard
        ((seg_not_present ^ 1) << 15) |
3764 8d18e893 bellard
        (seg_32bit << 22) |
3765 8d18e893 bellard
        (limit_in_pages << 23) |
3766 8d18e893 bellard
        (useable << 20) |
3767 8d18e893 bellard
        (lm << 21) |
3768 8d18e893 bellard
        0x7000;
3769 8d18e893 bellard
3770 8d18e893 bellard
    /* Install the new entry ...  */
3771 8d18e893 bellard
install:
3772 8d18e893 bellard
    lp = (uint32_t *)(gdt_table + ldt_info.entry_number);
3773 8d18e893 bellard
    lp[0] = tswap32(entry_1);
3774 8d18e893 bellard
    lp[1] = tswap32(entry_2);
3775 8d18e893 bellard
    return 0;
3776 8d18e893 bellard
}
3777 8d18e893 bellard
3778 8fcd3692 blueswir1
static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
3779 8d18e893 bellard
{
3780 8d18e893 bellard
    struct target_modify_ldt_ldt_s *target_ldt_info;
3781 8d18e893 bellard
    uint64_t *gdt_table = g2h(env->gdt.base);
3782 8d18e893 bellard
    uint32_t base_addr, limit, flags;
3783 8d18e893 bellard
    int seg_32bit, contents, read_exec_only, limit_in_pages, idx;
3784 8d18e893 bellard
    int seg_not_present, useable, lm;
3785 8d18e893 bellard
    uint32_t *lp, entry_1, entry_2;
3786 8d18e893 bellard
3787 8d18e893 bellard
    lock_user_struct(VERIFY_WRITE, target_ldt_info, ptr, 1);
3788 8d18e893 bellard
    if (!target_ldt_info)
3789 8d18e893 bellard
        return -TARGET_EFAULT;
3790 8d18e893 bellard
    idx = tswap32(target_ldt_info->entry_number);
3791 8d18e893 bellard
    if (idx < TARGET_GDT_ENTRY_TLS_MIN ||
3792 8d18e893 bellard
        idx > TARGET_GDT_ENTRY_TLS_MAX) {
3793 8d18e893 bellard
        unlock_user_struct(target_ldt_info, ptr, 1);
3794 8d18e893 bellard
        return -TARGET_EINVAL;
3795 8d18e893 bellard
    }
3796 8d18e893 bellard
    lp = (uint32_t *)(gdt_table + idx);
3797 8d18e893 bellard
    entry_1 = tswap32(lp[0]);
3798 8d18e893 bellard
    entry_2 = tswap32(lp[1]);
3799 8d18e893 bellard
    
3800 8d18e893 bellard
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
3801 8d18e893 bellard
    contents = (entry_2 >> 10) & 3;
3802 8d18e893 bellard
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
3803 8d18e893 bellard
    seg_32bit = (entry_2 >> 22) & 1;
3804 8d18e893 bellard
    limit_in_pages = (entry_2 >> 23) & 1;
3805 8d18e893 bellard
    useable = (entry_2 >> 20) & 1;
3806 8d18e893 bellard
#ifdef TARGET_ABI32
3807 8d18e893 bellard
    lm = 0;
3808 8d18e893 bellard
#else
3809 8d18e893 bellard
    lm = (entry_2 >> 21) & 1;
3810 8d18e893 bellard
#endif
3811 8d18e893 bellard
    flags = (seg_32bit << 0) | (contents << 1) |
3812 8d18e893 bellard
        (read_exec_only << 3) | (limit_in_pages << 4) |
3813 8d18e893 bellard
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
3814 8d18e893 bellard
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
3815 8d18e893 bellard
    base_addr = (entry_1 >> 16) | 
3816 8d18e893 bellard
        (entry_2 & 0xff000000) | 
3817 8d18e893 bellard
        ((entry_2 & 0xff) << 16);
3818 8d18e893 bellard
    target_ldt_info->base_addr = tswapl(base_addr);
3819 8d18e893 bellard
    target_ldt_info->limit = tswap32(limit);
3820 8d18e893 bellard
    target_ldt_info->flags = tswap32(flags);
3821 8d18e893 bellard
    unlock_user_struct(target_ldt_info, ptr, 1);
3822 8d18e893 bellard
    return 0;
3823 8d18e893 bellard
}
3824 4583f589 blueswir1
#endif /* TARGET_I386 && TARGET_ABI32 */
3825 8d18e893 bellard
3826 d2fd1af7 bellard
#ifndef TARGET_ABI32
3827 8fcd3692 blueswir1
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
3828 d2fd1af7 bellard
{
3829 1add8698 Juan Quintela
    abi_long ret = 0;
3830 d2fd1af7 bellard
    abi_ulong val;
3831 d2fd1af7 bellard
    int idx;
3832 1add8698 Juan Quintela
3833 d2fd1af7 bellard
    switch(code) {
3834 d2fd1af7 bellard
    case TARGET_ARCH_SET_GS:
3835 d2fd1af7 bellard
    case TARGET_ARCH_SET_FS:
3836 d2fd1af7 bellard
        if (code == TARGET_ARCH_SET_GS)
3837 d2fd1af7 bellard
            idx = R_GS;
3838 d2fd1af7 bellard
        else
3839 d2fd1af7 bellard
            idx = R_FS;
3840 d2fd1af7 bellard
        cpu_x86_load_seg(env, idx, 0);
3841 d2fd1af7 bellard
        env->segs[idx].base = addr;
3842 d2fd1af7 bellard
        break;
3843 d2fd1af7 bellard
    case TARGET_ARCH_GET_GS:
3844 d2fd1af7 bellard
    case TARGET_ARCH_GET_FS:
3845 d2fd1af7 bellard
        if (code == TARGET_ARCH_GET_GS)
3846 d2fd1af7 bellard
            idx = R_GS;
3847 d2fd1af7 bellard
        else
3848 d2fd1af7 bellard
            idx = R_FS;
3849 d2fd1af7 bellard
        val = env->segs[idx].base;
3850 d2fd1af7 bellard
        if (put_user(val, addr, abi_ulong))
3851 1add8698 Juan Quintela
            ret = -TARGET_EFAULT;
3852 d2fd1af7 bellard
        break;
3853 d2fd1af7 bellard
    default:
3854 d2fd1af7 bellard
        ret = -TARGET_EINVAL;
3855 d2fd1af7 bellard
        break;
3856 d2fd1af7 bellard
    }
3857 1add8698 Juan Quintela
    return ret;
3858 d2fd1af7 bellard
}
3859 d2fd1af7 bellard
#endif
3860 d2fd1af7 bellard
3861 2ab83ea7 bellard
#endif /* defined(TARGET_I386) */
3862 2ab83ea7 bellard
3863 05098a93 Riku Voipio
#define NEW_STACK_SIZE 0x40000
3864 d865bab5 pbrook
3865 05098a93 Riku Voipio
#if defined(CONFIG_USE_NPTL)
3866 d865bab5 pbrook
3867 d865bab5 pbrook
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
3868 d865bab5 pbrook
typedef struct {
3869 d865bab5 pbrook
    CPUState *env;
3870 d865bab5 pbrook
    pthread_mutex_t mutex;
3871 d865bab5 pbrook
    pthread_cond_t cond;
3872 d865bab5 pbrook
    pthread_t thread;
3873 d865bab5 pbrook
    uint32_t tid;
3874 d865bab5 pbrook
    abi_ulong child_tidptr;
3875 d865bab5 pbrook
    abi_ulong parent_tidptr;
3876 d865bab5 pbrook
    sigset_t sigmask;
3877 d865bab5 pbrook
} new_thread_info;
3878 d865bab5 pbrook
3879 d865bab5 pbrook
static void *clone_func(void *arg)
3880 d865bab5 pbrook
{
3881 d865bab5 pbrook
    new_thread_info *info = arg;
3882 d865bab5 pbrook
    CPUState *env;
3883 edf8e2af Mika Westerberg
    TaskState *ts;
3884 d865bab5 pbrook
3885 d865bab5 pbrook
    env = info->env;
3886 d865bab5 pbrook
    thread_env = env;
3887 edf8e2af Mika Westerberg
    ts = (TaskState *)thread_env->opaque;
3888 d865bab5 pbrook
    info->tid = gettid();
3889 1e9fa730 Nathan Froyd
    env->host_tid = info->tid;
3890 edf8e2af Mika Westerberg
    task_settid(ts);
3891 d865bab5 pbrook
    if (info->child_tidptr)
3892 d865bab5 pbrook
        put_user_u32(info->tid, info->child_tidptr);
3893 d865bab5 pbrook
    if (info->parent_tidptr)
3894 d865bab5 pbrook
        put_user_u32(info->tid, info->parent_tidptr);
3895 d865bab5 pbrook
    /* Enable signals.  */
3896 d865bab5 pbrook
    sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
3897 d865bab5 pbrook
    /* Signal to the parent that we're ready.  */
3898 d865bab5 pbrook
    pthread_mutex_lock(&info->mutex);
3899 d865bab5 pbrook
    pthread_cond_broadcast(&info->cond);
3900 d865bab5 pbrook
    pthread_mutex_unlock(&info->mutex);
3901 d865bab5 pbrook
    /* Wait until the parent has finshed initializing the tls state.  */
3902 d865bab5 pbrook
    pthread_mutex_lock(&clone_lock);
3903 d865bab5 pbrook
    pthread_mutex_unlock(&clone_lock);
3904 d865bab5 pbrook
    cpu_loop(env);
3905 d865bab5 pbrook
    /* never exits */
3906 d865bab5 pbrook
    return NULL;
3907 d865bab5 pbrook
}
3908 d865bab5 pbrook
#else
3909 1b6b029e bellard
3910 1b6b029e bellard
static int clone_func(void *arg)
3911 1b6b029e bellard
{
3912 2ab83ea7 bellard
    CPUState *env = arg;
3913 1b6b029e bellard
    cpu_loop(env);
3914 1b6b029e bellard
    /* never exits */
3915 1b6b029e bellard
    return 0;
3916 1b6b029e bellard
}
3917 d865bab5 pbrook
#endif
3918 1b6b029e bellard
3919 0da46a6e ths
/* do_fork() Must return host values and target errnos (unlike most
3920 0da46a6e ths
   do_*() functions). */
3921 d865bab5 pbrook
static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3922 d865bab5 pbrook
                   abi_ulong parent_tidptr, target_ulong newtls,
3923 d865bab5 pbrook
                   abi_ulong child_tidptr)
3924 1b6b029e bellard
{
3925 1b6b029e bellard
    int ret;
3926 5cd4393b bellard
    TaskState *ts;
3927 2ab83ea7 bellard
    CPUState *new_env;
3928 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3929 d865bab5 pbrook
    unsigned int nptl_flags;
3930 d865bab5 pbrook
    sigset_t sigmask;
3931 9190749f Riku Voipio
#else
3932 9190749f Riku Voipio
    uint8_t *new_stack;
3933 d865bab5 pbrook
#endif
3934 3b46e624 ths
3935 436d124b balrog
    /* Emulate vfork() with fork() */
3936 436d124b balrog
    if (flags & CLONE_VFORK)
3937 436d124b balrog
        flags &= ~(CLONE_VFORK | CLONE_VM);
3938 436d124b balrog
3939 1b6b029e bellard
    if (flags & CLONE_VM) {
3940 edf8e2af Mika Westerberg
        TaskState *parent_ts = (TaskState *)env->opaque;
3941 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3942 d865bab5 pbrook
        new_thread_info info;
3943 d865bab5 pbrook
        pthread_attr_t attr;
3944 bd0c5661 pbrook
#endif
3945 48e15fc2 Nathan Froyd
        ts = qemu_mallocz(sizeof(TaskState));
3946 624f7979 pbrook
        init_task_state(ts);
3947 1b6b029e bellard
        /* we create a new CPU instance. */
3948 c5be9f08 ths
        new_env = cpu_copy(env);
3949 b4558d74 Blue Swirl
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
3950 b4558d74 Blue Swirl
        cpu_reset(new_env);
3951 b4558d74 Blue Swirl
#endif
3952 6e68e076 pbrook
        /* Init regs that differ from the parent.  */
3953 6e68e076 pbrook
        cpu_clone_regs(new_env, newsp);
3954 5cd4393b bellard
        new_env->opaque = ts;
3955 edf8e2af Mika Westerberg
        ts->bprm = parent_ts->bprm;
3956 edf8e2af Mika Westerberg
        ts->info = parent_ts->info;
3957 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
3958 d865bab5 pbrook
        nptl_flags = flags;
3959 d865bab5 pbrook
        flags &= ~CLONE_NPTL_FLAGS2;
3960 d865bab5 pbrook
3961 c2764719 pbrook
        if (nptl_flags & CLONE_CHILD_CLEARTID) {
3962 c2764719 pbrook
            ts->child_tidptr = child_tidptr;
3963 c2764719 pbrook
        }
3964 c2764719 pbrook
3965 d865bab5 pbrook
        if (nptl_flags & CLONE_SETTLS)
3966 d865bab5 pbrook
            cpu_set_tls (new_env, newtls);
3967 d865bab5 pbrook
3968 d865bab5 pbrook
        /* Grab a mutex so that thread setup appears atomic.  */
3969 d865bab5 pbrook
        pthread_mutex_lock(&clone_lock);
3970 d865bab5 pbrook
3971 d865bab5 pbrook
        memset(&info, 0, sizeof(info));
3972 d865bab5 pbrook
        pthread_mutex_init(&info.mutex, NULL);
3973 d865bab5 pbrook
        pthread_mutex_lock(&info.mutex);
3974 d865bab5 pbrook
        pthread_cond_init(&info.cond, NULL);
3975 d865bab5 pbrook
        info.env = new_env;
3976 d865bab5 pbrook
        if (nptl_flags & CLONE_CHILD_SETTID)
3977 d865bab5 pbrook
            info.child_tidptr = child_tidptr;
3978 d865bab5 pbrook
        if (nptl_flags & CLONE_PARENT_SETTID)
3979 d865bab5 pbrook
            info.parent_tidptr = parent_tidptr;
3980 d865bab5 pbrook
3981 d865bab5 pbrook
        ret = pthread_attr_init(&attr);
3982 48e15fc2 Nathan Froyd
        ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
3983 48e15fc2 Nathan Froyd
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
3984 d865bab5 pbrook
        /* It is not safe to deliver signals until the child has finished
3985 d865bab5 pbrook
           initializing, so temporarily block all signals.  */
3986 d865bab5 pbrook
        sigfillset(&sigmask);
3987 d865bab5 pbrook
        sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask);
3988 d865bab5 pbrook
3989 d865bab5 pbrook
        ret = pthread_create(&info.thread, &attr, clone_func, &info);
3990 c2764719 pbrook
        /* TODO: Free new CPU state if thread creation failed.  */
3991 d865bab5 pbrook
3992 d865bab5 pbrook
        sigprocmask(SIG_SETMASK, &info.sigmask, NULL);
3993 d865bab5 pbrook
        pthread_attr_destroy(&attr);
3994 d865bab5 pbrook
        if (ret == 0) {
3995 d865bab5 pbrook
            /* Wait for the child to initialize.  */
3996 d865bab5 pbrook
            pthread_cond_wait(&info.cond, &info.mutex);
3997 d865bab5 pbrook
            ret = info.tid;
3998 d865bab5 pbrook
            if (flags & CLONE_PARENT_SETTID)
3999 d865bab5 pbrook
                put_user_u32(ret, parent_tidptr);
4000 d865bab5 pbrook
        } else {
4001 d865bab5 pbrook
            ret = -1;
4002 d865bab5 pbrook
        }
4003 d865bab5 pbrook
        pthread_mutex_unlock(&info.mutex);
4004 d865bab5 pbrook
        pthread_cond_destroy(&info.cond);
4005 d865bab5 pbrook
        pthread_mutex_destroy(&info.mutex);
4006 d865bab5 pbrook
        pthread_mutex_unlock(&clone_lock);
4007 d865bab5 pbrook
#else
4008 d865bab5 pbrook
        if (flags & CLONE_NPTL_FLAGS2)
4009 d865bab5 pbrook
            return -EINVAL;
4010 d865bab5 pbrook
        /* This is probably going to die very quickly, but do it anyway.  */
4011 48e15fc2 Nathan Froyd
        new_stack = qemu_mallocz (NEW_STACK_SIZE);
4012 27725c1d bellard
#ifdef __ia64__
4013 60e99246 Aurelien Jarno
        ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
4014 27725c1d bellard
#else
4015 27725c1d bellard
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
4016 27725c1d bellard
#endif
4017 d865bab5 pbrook
#endif
4018 1b6b029e bellard
    } else {
4019 1b6b029e bellard
        /* if no CLONE_VM, we consider it is a fork */
4020 d865bab5 pbrook
        if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
4021 1b6b029e bellard
            return -EINVAL;
4022 d865bab5 pbrook
        fork_start();
4023 1b6b029e bellard
        ret = fork();
4024 d865bab5 pbrook
        if (ret == 0) {
4025 2b1319c8 aurel32
            /* Child Process.  */
4026 d865bab5 pbrook
            cpu_clone_regs(env, newsp);
4027 d865bab5 pbrook
            fork_end(1);
4028 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
4029 2b1319c8 aurel32
            /* There is a race condition here.  The parent process could
4030 2b1319c8 aurel32
               theoretically read the TID in the child process before the child
4031 2b1319c8 aurel32
               tid is set.  This would require using either ptrace
4032 2b1319c8 aurel32
               (not implemented) or having *_tidptr to point at a shared memory
4033 2b1319c8 aurel32
               mapping.  We can't repeat the spinlock hack used above because
4034 2b1319c8 aurel32
               the child process gets its own copy of the lock.  */
4035 d865bab5 pbrook
            if (flags & CLONE_CHILD_SETTID)
4036 d865bab5 pbrook
                put_user_u32(gettid(), child_tidptr);
4037 d865bab5 pbrook
            if (flags & CLONE_PARENT_SETTID)
4038 d865bab5 pbrook
                put_user_u32(gettid(), parent_tidptr);
4039 d865bab5 pbrook
            ts = (TaskState *)env->opaque;
4040 d865bab5 pbrook
            if (flags & CLONE_SETTLS)
4041 d865bab5 pbrook
                cpu_set_tls (env, newtls);
4042 c2764719 pbrook
            if (flags & CLONE_CHILD_CLEARTID)
4043 c2764719 pbrook
                ts->child_tidptr = child_tidptr;
4044 2b1319c8 aurel32
#endif
4045 d865bab5 pbrook
        } else {
4046 d865bab5 pbrook
            fork_end(0);
4047 d865bab5 pbrook
        }
4048 1b6b029e bellard
    }
4049 1b6b029e bellard
    return ret;
4050 1b6b029e bellard
}
4051 1b6b029e bellard
4052 5f106811 Arnaud Patard (Rtp)
/* warning : doesn't handle linux specific flags... */
4053 5f106811 Arnaud Patard (Rtp)
static int target_to_host_fcntl_cmd(int cmd)
4054 5f106811 Arnaud Patard (Rtp)
{
4055 5f106811 Arnaud Patard (Rtp)
    switch(cmd) {
4056 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_DUPFD:
4057 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETFD:
4058 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETFD:
4059 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETFL:
4060 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETFL:
4061 5f106811 Arnaud Patard (Rtp)
            return cmd;
4062 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETLK:
4063 5f106811 Arnaud Patard (Rtp)
            return F_GETLK;
4064 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLK:
4065 5f106811 Arnaud Patard (Rtp)
            return F_SETLK;
4066 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLKW:
4067 5f106811 Arnaud Patard (Rtp)
            return F_SETLKW;
4068 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETOWN:
4069 5f106811 Arnaud Patard (Rtp)
            return F_GETOWN;
4070 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETOWN:
4071 5f106811 Arnaud Patard (Rtp)
            return F_SETOWN;
4072 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETSIG:
4073 5f106811 Arnaud Patard (Rtp)
            return F_GETSIG;
4074 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETSIG:
4075 5f106811 Arnaud Patard (Rtp)
            return F_SETSIG;
4076 5f106811 Arnaud Patard (Rtp)
#if TARGET_ABI_BITS == 32
4077 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_GETLK64:
4078 5f106811 Arnaud Patard (Rtp)
            return F_GETLK64;
4079 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLK64:
4080 5f106811 Arnaud Patard (Rtp)
            return F_SETLK64;
4081 5f106811 Arnaud Patard (Rtp)
        case TARGET_F_SETLKW64:
4082 5f106811 Arnaud Patard (Rtp)
            return F_SETLKW64;
4083 5f106811 Arnaud Patard (Rtp)
#endif
4084 7e22e546 Ulrich Hecht
        case TARGET_F_SETLEASE:
4085 7e22e546 Ulrich Hecht
            return F_SETLEASE;
4086 7e22e546 Ulrich Hecht
        case TARGET_F_GETLEASE:
4087 7e22e546 Ulrich Hecht
            return F_GETLEASE;
4088 fbd5de9b malc
#ifdef F_DUPFD_CLOEXEC
4089 7e22e546 Ulrich Hecht
        case TARGET_F_DUPFD_CLOEXEC:
4090 7e22e546 Ulrich Hecht
            return F_DUPFD_CLOEXEC;
4091 fbd5de9b malc
#endif
4092 7e22e546 Ulrich Hecht
        case TARGET_F_NOTIFY:
4093 7e22e546 Ulrich Hecht
            return F_NOTIFY;
4094 5f106811 Arnaud Patard (Rtp)
        default:
4095 5f106811 Arnaud Patard (Rtp)
            return -TARGET_EINVAL;
4096 5f106811 Arnaud Patard (Rtp)
    }
4097 5f106811 Arnaud Patard (Rtp)
    return -TARGET_EINVAL;
4098 5f106811 Arnaud Patard (Rtp)
}
4099 5f106811 Arnaud Patard (Rtp)
4100 992f48a0 blueswir1
static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
4101 7775e9ec bellard
{
4102 7775e9ec bellard
    struct flock fl;
4103 53a5960a pbrook
    struct target_flock *target_fl;
4104 43f238d7 ths
    struct flock64 fl64;
4105 43f238d7 ths
    struct target_flock64 *target_fl64;
4106 992f48a0 blueswir1
    abi_long ret;
4107 5f106811 Arnaud Patard (Rtp)
    int host_cmd = target_to_host_fcntl_cmd(cmd);
4108 5f106811 Arnaud Patard (Rtp)
4109 5f106811 Arnaud Patard (Rtp)
    if (host_cmd == -TARGET_EINVAL)
4110 5f106811 Arnaud Patard (Rtp)
            return host_cmd;
4111 53a5960a pbrook
4112 7775e9ec bellard
    switch(cmd) {
4113 7775e9ec bellard
    case TARGET_F_GETLK:
4114 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4115 579a97f7 bellard
            return -TARGET_EFAULT;
4116 5813427b ths
        fl.l_type = tswap16(target_fl->l_type);
4117 5813427b ths
        fl.l_whence = tswap16(target_fl->l_whence);
4118 5813427b ths
        fl.l_start = tswapl(target_fl->l_start);
4119 5813427b ths
        fl.l_len = tswapl(target_fl->l_len);
4120 7e22e546 Ulrich Hecht
        fl.l_pid = tswap32(target_fl->l_pid);
4121 5813427b ths
        unlock_user_struct(target_fl, arg, 0);
4122 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4123 7775e9ec bellard
        if (ret == 0) {
4124 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
4125 579a97f7 bellard
                return -TARGET_EFAULT;
4126 7775e9ec bellard
            target_fl->l_type = tswap16(fl.l_type);
4127 7775e9ec bellard
            target_fl->l_whence = tswap16(fl.l_whence);
4128 7775e9ec bellard
            target_fl->l_start = tswapl(fl.l_start);
4129 7775e9ec bellard
            target_fl->l_len = tswapl(fl.l_len);
4130 7e22e546 Ulrich Hecht
            target_fl->l_pid = tswap32(fl.l_pid);
4131 53a5960a pbrook
            unlock_user_struct(target_fl, arg, 1);
4132 7775e9ec bellard
        }
4133 7775e9ec bellard
        break;
4134 3b46e624 ths
4135 7775e9ec bellard
    case TARGET_F_SETLK:
4136 7775e9ec bellard
    case TARGET_F_SETLKW:
4137 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl, arg, 1))
4138 579a97f7 bellard
            return -TARGET_EFAULT;
4139 7775e9ec bellard
        fl.l_type = tswap16(target_fl->l_type);
4140 7775e9ec bellard
        fl.l_whence = tswap16(target_fl->l_whence);
4141 7775e9ec bellard
        fl.l_start = tswapl(target_fl->l_start);
4142 7775e9ec bellard
        fl.l_len = tswapl(target_fl->l_len);
4143 7e22e546 Ulrich Hecht
        fl.l_pid = tswap32(target_fl->l_pid);
4144 53a5960a pbrook
        unlock_user_struct(target_fl, arg, 0);
4145 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl));
4146 7775e9ec bellard
        break;
4147 3b46e624 ths
4148 7775e9ec bellard
    case TARGET_F_GETLK64:
4149 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4150 579a97f7 bellard
            return -TARGET_EFAULT;
4151 5813427b ths
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4152 5813427b ths
        fl64.l_whence = tswap16(target_fl64->l_whence);
4153 5813427b ths
        fl64.l_start = tswapl(target_fl64->l_start);
4154 5813427b ths
        fl64.l_len = tswapl(target_fl64->l_len);
4155 7e22e546 Ulrich Hecht
        fl64.l_pid = tswap32(target_fl64->l_pid);
4156 5813427b ths
        unlock_user_struct(target_fl64, arg, 0);
4157 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4158 43f238d7 ths
        if (ret == 0) {
4159 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
4160 579a97f7 bellard
                return -TARGET_EFAULT;
4161 43f238d7 ths
            target_fl64->l_type = tswap16(fl64.l_type) >> 1;
4162 43f238d7 ths
            target_fl64->l_whence = tswap16(fl64.l_whence);
4163 43f238d7 ths
            target_fl64->l_start = tswapl(fl64.l_start);
4164 43f238d7 ths
            target_fl64->l_len = tswapl(fl64.l_len);
4165 7e22e546 Ulrich Hecht
            target_fl64->l_pid = tswap32(fl64.l_pid);
4166 43f238d7 ths
            unlock_user_struct(target_fl64, arg, 1);
4167 43f238d7 ths
        }
4168 9ee1fa2c bellard
        break;
4169 7775e9ec bellard
    case TARGET_F_SETLK64:
4170 7775e9ec bellard
    case TARGET_F_SETLKW64:
4171 579a97f7 bellard
        if (!lock_user_struct(VERIFY_READ, target_fl64, arg, 1))
4172 579a97f7 bellard
            return -TARGET_EFAULT;
4173 43f238d7 ths
        fl64.l_type = tswap16(target_fl64->l_type) >> 1;
4174 43f238d7 ths
        fl64.l_whence = tswap16(target_fl64->l_whence);
4175 43f238d7 ths
        fl64.l_start = tswapl(target_fl64->l_start);
4176 43f238d7 ths
        fl64.l_len = tswapl(target_fl64->l_len);
4177 7e22e546 Ulrich Hecht
        fl64.l_pid = tswap32(target_fl64->l_pid);
4178 43f238d7 ths
        unlock_user_struct(target_fl64, arg, 0);
4179 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, &fl64));
4180 7775e9ec bellard
        break;
4181 7775e9ec bellard
4182 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETFL:
4183 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, arg));
4184 9ee1fa2c bellard
        if (ret >= 0) {
4185 9ee1fa2c bellard
            ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
4186 9ee1fa2c bellard
        }
4187 ffa65c3b bellard
        break;
4188 ffa65c3b bellard
4189 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETFL:
4190 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
4191 5f106811 Arnaud Patard (Rtp)
        break;
4192 5f106811 Arnaud Patard (Rtp)
4193 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETOWN:
4194 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETOWN:
4195 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_SETSIG:
4196 5f106811 Arnaud Patard (Rtp)
    case TARGET_F_GETSIG:
4197 7e22e546 Ulrich Hecht
    case TARGET_F_SETLEASE:
4198 7e22e546 Ulrich Hecht
    case TARGET_F_GETLEASE:
4199 5f106811 Arnaud Patard (Rtp)
        ret = get_errno(fcntl(fd, host_cmd, arg));
4200 ffa65c3b bellard
        break;
4201 ffa65c3b bellard
4202 7775e9ec bellard
    default:
4203 9ee1fa2c bellard
        ret = get_errno(fcntl(fd, cmd, arg));
4204 7775e9ec bellard
        break;
4205 7775e9ec bellard
    }
4206 7775e9ec bellard
    return ret;
4207 7775e9ec bellard
}
4208 7775e9ec bellard
4209 67867308 bellard
#ifdef USE_UID16
4210 7775e9ec bellard
4211 67867308 bellard
static inline int high2lowuid(int uid)
4212 67867308 bellard
{
4213 67867308 bellard
    if (uid > 65535)
4214 67867308 bellard
        return 65534;
4215 67867308 bellard
    else
4216 67867308 bellard
        return uid;
4217 67867308 bellard
}
4218 67867308 bellard
4219 67867308 bellard
static inline int high2lowgid(int gid)
4220 67867308 bellard
{
4221 67867308 bellard
    if (gid > 65535)
4222 67867308 bellard
        return 65534;
4223 67867308 bellard
    else
4224 67867308 bellard
        return gid;
4225 67867308 bellard
}
4226 67867308 bellard
4227 67867308 bellard
static inline int low2highuid(int uid)
4228 67867308 bellard
{
4229 67867308 bellard
    if ((int16_t)uid == -1)
4230 67867308 bellard
        return -1;
4231 67867308 bellard
    else
4232 67867308 bellard
        return uid;
4233 67867308 bellard
}
4234 67867308 bellard
4235 67867308 bellard
static inline int low2highgid(int gid)
4236 67867308 bellard
{
4237 67867308 bellard
    if ((int16_t)gid == -1)
4238 67867308 bellard
        return -1;
4239 67867308 bellard
    else
4240 67867308 bellard
        return gid;
4241 67867308 bellard
}
4242 0c866a7e Riku Voipio
static inline int tswapid(int id)
4243 0c866a7e Riku Voipio
{
4244 0c866a7e Riku Voipio
    return tswap16(id);
4245 0c866a7e Riku Voipio
}
4246 0c866a7e Riku Voipio
#else /* !USE_UID16 */
4247 0c866a7e Riku Voipio
static inline int high2lowuid(int uid)
4248 0c866a7e Riku Voipio
{
4249 0c866a7e Riku Voipio
    return uid;
4250 0c866a7e Riku Voipio
}
4251 0c866a7e Riku Voipio
static inline int high2lowgid(int gid)
4252 0c866a7e Riku Voipio
{
4253 0c866a7e Riku Voipio
    return gid;
4254 0c866a7e Riku Voipio
}
4255 0c866a7e Riku Voipio
static inline int low2highuid(int uid)
4256 0c866a7e Riku Voipio
{
4257 0c866a7e Riku Voipio
    return uid;
4258 0c866a7e Riku Voipio
}
4259 0c866a7e Riku Voipio
static inline int low2highgid(int gid)
4260 0c866a7e Riku Voipio
{
4261 0c866a7e Riku Voipio
    return gid;
4262 0c866a7e Riku Voipio
}
4263 0c866a7e Riku Voipio
static inline int tswapid(int id)
4264 0c866a7e Riku Voipio
{
4265 0c866a7e Riku Voipio
    return tswap32(id);
4266 0c866a7e Riku Voipio
}
4267 67867308 bellard
#endif /* USE_UID16 */
4268 1b6b029e bellard
4269 31e31b8a bellard
void syscall_init(void)
4270 31e31b8a bellard
{
4271 2ab83ea7 bellard
    IOCTLEntry *ie;
4272 2ab83ea7 bellard
    const argtype *arg_type;
4273 2ab83ea7 bellard
    int size;
4274 b92c47c1 ths
    int i;
4275 2ab83ea7 bellard
4276 001faf32 Blue Swirl
#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
4277 5fafdf24 ths
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
4278 31e31b8a bellard
#include "syscall_types.h"
4279 31e31b8a bellard
#undef STRUCT
4280 31e31b8a bellard
#undef STRUCT_SPECIAL
4281 2ab83ea7 bellard
4282 2ab83ea7 bellard
    /* we patch the ioctl size if necessary. We rely on the fact that
4283 2ab83ea7 bellard
       no ioctl has all the bits at '1' in the size field */
4284 2ab83ea7 bellard
    ie = ioctl_entries;
4285 2ab83ea7 bellard
    while (ie->target_cmd != 0) {
4286 2ab83ea7 bellard
        if (((ie->target_cmd >> TARGET_IOC_SIZESHIFT) & TARGET_IOC_SIZEMASK) ==
4287 2ab83ea7 bellard
            TARGET_IOC_SIZEMASK) {
4288 2ab83ea7 bellard
            arg_type = ie->arg_type;
4289 2ab83ea7 bellard
            if (arg_type[0] != TYPE_PTR) {
4290 5fafdf24 ths
                fprintf(stderr, "cannot patch size for ioctl 0x%x\n",
4291 2ab83ea7 bellard
                        ie->target_cmd);
4292 2ab83ea7 bellard
                exit(1);
4293 2ab83ea7 bellard
            }
4294 2ab83ea7 bellard
            arg_type++;
4295 2ab83ea7 bellard
            size = thunk_type_size(arg_type, 0);
4296 5fafdf24 ths
            ie->target_cmd = (ie->target_cmd &
4297 2ab83ea7 bellard
                              ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) |
4298 2ab83ea7 bellard
                (size << TARGET_IOC_SIZESHIFT);
4299 2ab83ea7 bellard
        }
4300 b92c47c1 ths
4301 b92c47c1 ths
        /* Build target_to_host_errno_table[] table from
4302 b92c47c1 ths
         * host_to_target_errno_table[]. */
4303 b92c47c1 ths
        for (i=0; i < ERRNO_TABLE_SIZE; i++)
4304 b92c47c1 ths
                target_to_host_errno_table[host_to_target_errno_table[i]] = i;
4305 b92c47c1 ths
4306 2ab83ea7 bellard
        /* automatic consistency check if same arch */
4307 872ea0c0 balrog
#if (defined(__i386__) && defined(TARGET_I386) && defined(TARGET_ABI32)) || \
4308 872ea0c0 balrog
    (defined(__x86_64__) && defined(TARGET_X86_64))
4309 872ea0c0 balrog
        if (unlikely(ie->target_cmd != ie->host_cmd)) {
4310 872ea0c0 balrog
            fprintf(stderr, "ERROR: ioctl(%s): target=0x%x host=0x%x\n",
4311 872ea0c0 balrog
                    ie->name, ie->target_cmd, ie->host_cmd);
4312 2ab83ea7 bellard
        }
4313 2ab83ea7 bellard
#endif
4314 2ab83ea7 bellard
        ie++;
4315 2ab83ea7 bellard
    }
4316 31e31b8a bellard
}
4317 c573ff67 bellard
4318 992f48a0 blueswir1
#if TARGET_ABI_BITS == 32
4319 ce4defa0 pbrook
static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
4320 ce4defa0 pbrook
{
4321 af325d36 ths
#ifdef TARGET_WORDS_BIGENDIAN
4322 ce4defa0 pbrook
    return ((uint64_t)word0 << 32) | word1;
4323 ce4defa0 pbrook
#else
4324 ce4defa0 pbrook
    return ((uint64_t)word1 << 32) | word0;
4325 ce4defa0 pbrook
#endif
4326 ce4defa0 pbrook
}
4327 992f48a0 blueswir1
#else /* TARGET_ABI_BITS == 32 */
4328 32407103 j_mayer
static inline uint64_t target_offset64(uint64_t word0, uint64_t word1)
4329 32407103 j_mayer
{
4330 32407103 j_mayer
    return word0;
4331 32407103 j_mayer
}
4332 992f48a0 blueswir1
#endif /* TARGET_ABI_BITS != 32 */
4333 ce4defa0 pbrook
4334 ce4defa0 pbrook
#ifdef TARGET_NR_truncate64
4335 992f48a0 blueswir1
static inline abi_long target_truncate64(void *cpu_env, const char *arg1,
4336 992f48a0 blueswir1
                                         abi_long arg2,
4337 992f48a0 blueswir1
                                         abi_long arg3,
4338 992f48a0 blueswir1
                                         abi_long arg4)
4339 ce4defa0 pbrook
{
4340 ce4defa0 pbrook
#ifdef TARGET_ARM
4341 ce4defa0 pbrook
    if (((CPUARMState *)cpu_env)->eabi)
4342 ce4defa0 pbrook
      {
4343 ce4defa0 pbrook
        arg2 = arg3;
4344 ce4defa0 pbrook
        arg3 = arg4;
4345 ce4defa0 pbrook
      }
4346 ce4defa0 pbrook
#endif
4347 ce4defa0 pbrook
    return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
4348 ce4defa0 pbrook
}
4349 ce4defa0 pbrook
#endif
4350 ce4defa0 pbrook
4351 ce4defa0 pbrook
#ifdef TARGET_NR_ftruncate64
4352 992f48a0 blueswir1
static inline abi_long target_ftruncate64(void *cpu_env, abi_long arg1,
4353 992f48a0 blueswir1
                                          abi_long arg2,
4354 992f48a0 blueswir1
                                          abi_long arg3,
4355 992f48a0 blueswir1
                                          abi_long arg4)
4356 ce4defa0 pbrook
{
4357 ce4defa0 pbrook
#ifdef TARGET_ARM
4358 ce4defa0 pbrook
    if (((CPUARMState *)cpu_env)->eabi)
4359 ce4defa0 pbrook
      {
4360 ce4defa0 pbrook
        arg2 = arg3;
4361 ce4defa0 pbrook
        arg3 = arg4;
4362 ce4defa0 pbrook
      }
4363 ce4defa0 pbrook
#endif
4364 ce4defa0 pbrook
    return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
4365 ce4defa0 pbrook
}
4366 ce4defa0 pbrook
#endif
4367 ce4defa0 pbrook
4368 579a97f7 bellard
static inline abi_long target_to_host_timespec(struct timespec *host_ts,
4369 579a97f7 bellard
                                               abi_ulong target_addr)
4370 53a5960a pbrook
{
4371 53a5960a pbrook
    struct target_timespec *target_ts;
4372 53a5960a pbrook
4373 579a97f7 bellard
    if (!lock_user_struct(VERIFY_READ, target_ts, target_addr, 1))
4374 579a97f7 bellard
        return -TARGET_EFAULT;
4375 53a5960a pbrook
    host_ts->tv_sec = tswapl(target_ts->tv_sec);
4376 53a5960a pbrook
    host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
4377 53a5960a pbrook
    unlock_user_struct(target_ts, target_addr, 0);
4378 b255bfa8 bellard
    return 0;
4379 53a5960a pbrook
}
4380 53a5960a pbrook
4381 579a97f7 bellard
static inline abi_long host_to_target_timespec(abi_ulong target_addr,
4382 579a97f7 bellard
                                               struct timespec *host_ts)
4383 53a5960a pbrook
{
4384 53a5960a pbrook
    struct target_timespec *target_ts;
4385 53a5960a pbrook
4386 579a97f7 bellard
    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_addr, 0))
4387 579a97f7 bellard
        return -TARGET_EFAULT;
4388 53a5960a pbrook
    target_ts->tv_sec = tswapl(host_ts->tv_sec);
4389 53a5960a pbrook
    target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
4390 53a5960a pbrook
    unlock_user_struct(target_ts, target_addr, 1);
4391 b255bfa8 bellard
    return 0;
4392 53a5960a pbrook
}
4393 53a5960a pbrook
4394 9d33b76b aurel32
#if defined(TARGET_NR_stat64) || defined(TARGET_NR_newfstatat)
4395 6a24a778 balrog
static inline abi_long host_to_target_stat64(void *cpu_env,
4396 6a24a778 balrog
                                             abi_ulong target_addr,
4397 6a24a778 balrog
                                             struct stat *host_st)
4398 6a24a778 balrog
{
4399 6a24a778 balrog
#ifdef TARGET_ARM
4400 6a24a778 balrog
    if (((CPUARMState *)cpu_env)->eabi) {
4401 6a24a778 balrog
        struct target_eabi_stat64 *target_st;
4402 6a24a778 balrog
4403 6a24a778 balrog
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4404 6a24a778 balrog
            return -TARGET_EFAULT;
4405 6a24a778 balrog
        memset(target_st, 0, sizeof(struct target_eabi_stat64));
4406 6a24a778 balrog
        __put_user(host_st->st_dev, &target_st->st_dev);
4407 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->st_ino);
4408 6a24a778 balrog
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4409 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->__st_ino);
4410 6a24a778 balrog
#endif
4411 6a24a778 balrog
        __put_user(host_st->st_mode, &target_st->st_mode);
4412 6a24a778 balrog
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4413 6a24a778 balrog
        __put_user(host_st->st_uid, &target_st->st_uid);
4414 6a24a778 balrog
        __put_user(host_st->st_gid, &target_st->st_gid);
4415 6a24a778 balrog
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4416 6a24a778 balrog
        __put_user(host_st->st_size, &target_st->st_size);
4417 6a24a778 balrog
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4418 6a24a778 balrog
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4419 6a24a778 balrog
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4420 6a24a778 balrog
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4421 6a24a778 balrog
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4422 6a24a778 balrog
        unlock_user_struct(target_st, target_addr, 1);
4423 6a24a778 balrog
    } else
4424 6a24a778 balrog
#endif
4425 6a24a778 balrog
    {
4426 ed18c5ce Richard Henderson
#if TARGET_ABI_BITS == 64 && !defined(TARGET_ALPHA)
4427 9d33b76b aurel32
        struct target_stat *target_st;
4428 9d33b76b aurel32
#else
4429 6a24a778 balrog
        struct target_stat64 *target_st;
4430 9d33b76b aurel32
#endif
4431 6a24a778 balrog
4432 6a24a778 balrog
        if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0))
4433 6a24a778 balrog
            return -TARGET_EFAULT;
4434 9d33b76b aurel32
        memset(target_st, 0, sizeof(*target_st));
4435 6a24a778 balrog
        __put_user(host_st->st_dev, &target_st->st_dev);
4436 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->st_ino);
4437 6a24a778 balrog
#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
4438 6a24a778 balrog
        __put_user(host_st->st_ino, &target_st->__st_ino);
4439 6a24a778 balrog
#endif
4440 6a24a778 balrog
        __put_user(host_st->st_mode, &target_st->st_mode);
4441 6a24a778 balrog
        __put_user(host_st->st_nlink, &target_st->st_nlink);
4442 6a24a778 balrog
        __put_user(host_st->st_uid, &target_st->st_uid);
4443 6a24a778 balrog
        __put_user(host_st->st_gid, &target_st->st_gid);
4444 6a24a778 balrog
        __put_user(host_st->st_rdev, &target_st->st_rdev);
4445 6a24a778 balrog
        /* XXX: better use of kernel struct */
4446 6a24a778 balrog
        __put_user(host_st->st_size, &target_st->st_size);
4447 6a24a778 balrog
        __put_user(host_st->st_blksize, &target_st->st_blksize);
4448 6a24a778 balrog
        __put_user(host_st->st_blocks, &target_st->st_blocks);
4449 6a24a778 balrog
        __put_user(host_st->st_atime, &target_st->target_st_atime);
4450 6a24a778 balrog
        __put_user(host_st->st_mtime, &target_st->target_st_mtime);
4451 6a24a778 balrog
        __put_user(host_st->st_ctime, &target_st->target_st_ctime);
4452 6a24a778 balrog
        unlock_user_struct(target_st, target_addr, 1);
4453 6a24a778 balrog
    }
4454 6a24a778 balrog
4455 6a24a778 balrog
    return 0;
4456 6a24a778 balrog
}
4457 6a24a778 balrog
#endif
4458 6a24a778 balrog
4459 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
4460 bd0c5661 pbrook
/* ??? Using host futex calls even when target atomic operations
4461 bd0c5661 pbrook
   are not really atomic probably breaks things.  However implementing
4462 bd0c5661 pbrook
   futexes locally would make futexes shared between multiple processes
4463 bd0c5661 pbrook
   tricky.  However they're probably useless because guest atomic
4464 bd0c5661 pbrook
   operations won't work either.  */
4465 8fcd3692 blueswir1
static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
4466 8fcd3692 blueswir1
                    target_ulong uaddr2, int val3)
4467 bd0c5661 pbrook
{
4468 bd0c5661 pbrook
    struct timespec ts, *pts;
4469 a16aae0c Nathan Froyd
    int base_op;
4470 bd0c5661 pbrook
4471 bd0c5661 pbrook
    /* ??? We assume FUTEX_* constants are the same on both host
4472 bd0c5661 pbrook
       and target.  */
4473 a29ccd63 Martin Mohring
#ifdef FUTEX_CMD_MASK
4474 a16aae0c Nathan Froyd
    base_op = op & FUTEX_CMD_MASK;
4475 a29ccd63 Martin Mohring
#else
4476 a16aae0c Nathan Froyd
    base_op = op;
4477 a29ccd63 Martin Mohring
#endif
4478 a16aae0c Nathan Froyd
    switch (base_op) {
4479 bd0c5661 pbrook
    case FUTEX_WAIT:
4480 bd0c5661 pbrook
        if (timeout) {
4481 bd0c5661 pbrook
            pts = &ts;
4482 bd0c5661 pbrook
            target_to_host_timespec(pts, timeout);
4483 bd0c5661 pbrook
        } else {
4484 bd0c5661 pbrook
            pts = NULL;
4485 bd0c5661 pbrook
        }
4486 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, tswap32(val),
4487 bd0c5661 pbrook
                         pts, NULL, 0));
4488 bd0c5661 pbrook
    case FUTEX_WAKE:
4489 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4490 bd0c5661 pbrook
    case FUTEX_FD:
4491 a29ccd63 Martin Mohring
        return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0));
4492 bd0c5661 pbrook
    case FUTEX_REQUEUE:
4493 bd0c5661 pbrook
    case FUTEX_CMP_REQUEUE:
4494 a16aae0c Nathan Froyd
    case FUTEX_WAKE_OP:
4495 a16aae0c Nathan Froyd
        /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the
4496 a16aae0c Nathan Froyd
           TIMEOUT parameter is interpreted as a uint32_t by the kernel.
4497 a16aae0c Nathan Froyd
           But the prototype takes a `struct timespec *'; insert casts
4498 a16aae0c Nathan Froyd
           to satisfy the compiler.  We do not need to tswap TIMEOUT
4499 a16aae0c Nathan Froyd
           since it's not compared to guest memory.  */
4500 a16aae0c Nathan Froyd
        pts = (struct timespec *)(uintptr_t) timeout;
4501 a16aae0c Nathan Froyd
        return get_errno(sys_futex(g2h(uaddr), op, val, pts,
4502 a16aae0c Nathan Froyd
                                   g2h(uaddr2),
4503 a16aae0c Nathan Froyd
                                   (base_op == FUTEX_CMP_REQUEUE
4504 a16aae0c Nathan Froyd
                                    ? tswap32(val3)
4505 a16aae0c Nathan Froyd
                                    : val3)));
4506 bd0c5661 pbrook
    default:
4507 bd0c5661 pbrook
        return -TARGET_ENOSYS;
4508 bd0c5661 pbrook
    }
4509 bd0c5661 pbrook
}
4510 bd0c5661 pbrook
#endif
4511 bd0c5661 pbrook
4512 1d9d8b55 pbrook
/* Map host to target signal numbers for the wait family of syscalls.
4513 1d9d8b55 pbrook
   Assume all other status bits are the same.  */
4514 1d9d8b55 pbrook
static int host_to_target_waitstatus(int status)
4515 1d9d8b55 pbrook
{
4516 1d9d8b55 pbrook
    if (WIFSIGNALED(status)) {
4517 1d9d8b55 pbrook
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
4518 1d9d8b55 pbrook
    }
4519 1d9d8b55 pbrook
    if (WIFSTOPPED(status)) {
4520 1d9d8b55 pbrook
        return (host_to_target_signal(WSTOPSIG(status)) << 8)
4521 1d9d8b55 pbrook
               | (status & 0xff);
4522 1d9d8b55 pbrook
    }
4523 1d9d8b55 pbrook
    return status;
4524 1d9d8b55 pbrook
}
4525 1d9d8b55 pbrook
4526 a745ec6d pbrook
int get_osversion(void)
4527 a745ec6d pbrook
{
4528 a745ec6d pbrook
    static int osversion;
4529 a745ec6d pbrook
    struct new_utsname buf;
4530 a745ec6d pbrook
    const char *s;
4531 a745ec6d pbrook
    int i, n, tmp;
4532 a745ec6d pbrook
    if (osversion)
4533 a745ec6d pbrook
        return osversion;
4534 a745ec6d pbrook
    if (qemu_uname_release && *qemu_uname_release) {
4535 a745ec6d pbrook
        s = qemu_uname_release;
4536 a745ec6d pbrook
    } else {
4537 a745ec6d pbrook
        if (sys_uname(&buf))
4538 a745ec6d pbrook
            return 0;
4539 a745ec6d pbrook
        s = buf.release;
4540 a745ec6d pbrook
    }
4541 a745ec6d pbrook
    tmp = 0;
4542 a745ec6d pbrook
    for (i = 0; i < 3; i++) {
4543 a745ec6d pbrook
        n = 0;
4544 a745ec6d pbrook
        while (*s >= '0' && *s <= '9') {
4545 a745ec6d pbrook
            n *= 10;
4546 a745ec6d pbrook
            n += *s - '0';
4547 a745ec6d pbrook
            s++;
4548 a745ec6d pbrook
        }
4549 a745ec6d pbrook
        tmp = (tmp << 8) + n;
4550 a745ec6d pbrook
        if (*s == '.')
4551 a745ec6d pbrook
            s++;
4552 a745ec6d pbrook
    }
4553 a745ec6d pbrook
    osversion = tmp;
4554 a745ec6d pbrook
    return osversion;
4555 a745ec6d pbrook
}
4556 a745ec6d pbrook
4557 0da46a6e ths
/* do_syscall() should always have a single exit point at the end so
4558 0da46a6e ths
   that actions, such as logging of syscall results, can be performed.
4559 0da46a6e ths
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
4560 992f48a0 blueswir1
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
4561 992f48a0 blueswir1
                    abi_long arg2, abi_long arg3, abi_long arg4,
4562 5945cfcb Peter Maydell
                    abi_long arg5, abi_long arg6, abi_long arg7,
4563 5945cfcb Peter Maydell
                    abi_long arg8)
4564 31e31b8a bellard
{
4565 992f48a0 blueswir1
    abi_long ret;
4566 31e31b8a bellard
    struct stat st;
4567 56c8f68f bellard
    struct statfs stfs;
4568 53a5960a pbrook
    void *p;
4569 3b46e624 ths
4570 72f03900 bellard
#ifdef DEBUG
4571 c573ff67 bellard
    gemu_log("syscall %d", num);
4572 72f03900 bellard
#endif
4573 b92c47c1 ths
    if(do_strace)
4574 b92c47c1 ths
        print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
4575 b92c47c1 ths
4576 31e31b8a bellard
    switch(num) {
4577 31e31b8a bellard
    case TARGET_NR_exit:
4578 2f7bb878 Juan Quintela
#ifdef CONFIG_USE_NPTL
4579 c2764719 pbrook
      /* In old applications this may be used to implement _exit(2).
4580 c2764719 pbrook
         However in threaded applictions it is used for thread termination,
4581 c2764719 pbrook
         and _exit_group is used for application termination.
4582 c2764719 pbrook
         Do thread termination if we have more then one thread.  */
4583 c2764719 pbrook
      /* FIXME: This probably breaks if a signal arrives.  We should probably
4584 c2764719 pbrook
         be disabling signals.  */
4585 c2764719 pbrook
      if (first_cpu->next_cpu) {
4586 1e9fa730 Nathan Froyd
          TaskState *ts;
4587 c2764719 pbrook
          CPUState **lastp;
4588 c2764719 pbrook
          CPUState *p;
4589 c2764719 pbrook
4590 c2764719 pbrook
          cpu_list_lock();
4591 c2764719 pbrook
          lastp = &first_cpu;
4592 c2764719 pbrook
          p = first_cpu;
4593 c2764719 pbrook
          while (p && p != (CPUState *)cpu_env) {
4594 c2764719 pbrook
              lastp = &p->next_cpu;
4595 c2764719 pbrook
              p = p->next_cpu;
4596 c2764719 pbrook
          }
4597 c2764719 pbrook
          /* If we didn't find the CPU for this thread then something is
4598 c2764719 pbrook
             horribly wrong.  */
4599 c2764719 pbrook
          if (!p)
4600 c2764719 pbrook
              abort();
4601 c2764719 pbrook
          /* Remove the CPU from the list.  */
4602 c2764719 pbrook
          *lastp = p->next_cpu;
4603 c2764719 pbrook
          cpu_list_unlock();
4604 1e9fa730 Nathan Froyd
          ts = ((CPUState *)cpu_env)->opaque;
4605 c2764719 pbrook
          if (ts->child_tidptr) {
4606 c2764719 pbrook
              put_user_u32(0, ts->child_tidptr);
4607 c2764719 pbrook
              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
4608 c2764719 pbrook
                        NULL, NULL, 0);
4609 c2764719 pbrook
          }
4610 48e15fc2 Nathan Froyd
          thread_env = NULL;
4611 48e15fc2 Nathan Froyd
          qemu_free(cpu_env);
4612 48e15fc2 Nathan Froyd
          qemu_free(ts);
4613 c2764719 pbrook
          pthread_exit(NULL);
4614 c2764719 pbrook
      }
4615 c2764719 pbrook
#endif
4616 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
4617 7d13299d bellard
        _mcleanup();
4618 7d13299d bellard
#endif
4619 e9009676 bellard
        gdb_exit(cpu_env, arg1);
4620 c2764719 pbrook
        _exit(arg1);
4621 31e31b8a bellard
        ret = 0; /* avoid warning */
4622 31e31b8a bellard
        break;
4623 31e31b8a bellard
    case TARGET_NR_read:
4624 38d840e6 aurel32
        if (arg3 == 0)
4625 38d840e6 aurel32
            ret = 0;
4626 38d840e6 aurel32
        else {
4627 38d840e6 aurel32
            if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
4628 38d840e6 aurel32
                goto efault;
4629 38d840e6 aurel32
            ret = get_errno(read(arg1, p, arg3));
4630 38d840e6 aurel32
            unlock_user(p, arg2, ret);
4631 38d840e6 aurel32
        }
4632 31e31b8a bellard
        break;
4633 31e31b8a bellard
    case TARGET_NR_write:
4634 579a97f7 bellard
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
4635 579a97f7 bellard
            goto efault;
4636 53a5960a pbrook
        ret = get_errno(write(arg1, p, arg3));
4637 53a5960a pbrook
        unlock_user(p, arg2, 0);
4638 31e31b8a bellard
        break;
4639 31e31b8a bellard
    case TARGET_NR_open:
4640 2f619698 bellard
        if (!(p = lock_user_string(arg1)))
4641 2f619698 bellard
            goto efault;
4642 53a5960a pbrook
        ret = get_errno(open(path(p),
4643 ffa65c3b bellard
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
4644 ffa65c3b bellard
                             arg3));
4645 53a5960a pbrook
        unlock_user(p, arg1, 0);
4646 31e31b8a bellard
        break;
4647 82424832 ths
#if defined(TARGET_NR_openat) && defined(__NR_openat)
4648 82424832 ths
    case TARGET_NR_openat:
4649 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4650 579a97f7 bellard
            goto efault;
4651 579a97f7 bellard
        ret = get_errno(sys_openat(arg1,
4652 579a97f7 bellard
                                   path(p),
4653 579a97f7 bellard
                                   target_to_host_bitmask(arg3, fcntl_flags_tbl),
4654 579a97f7 bellard
                                   arg4));
4655 579a97f7 bellard
        unlock_user(p, arg2, 0);
4656 82424832 ths
        break;
4657 82424832 ths
#endif
4658 31e31b8a bellard
    case TARGET_NR_close:
4659 31e31b8a bellard
        ret = get_errno(close(arg1));
4660 31e31b8a bellard
        break;
4661 31e31b8a bellard
    case TARGET_NR_brk:
4662 53a5960a pbrook
        ret = do_brk(arg1);
4663 31e31b8a bellard
        break;
4664 31e31b8a bellard
    case TARGET_NR_fork:
4665 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0));
4666 31e31b8a bellard
        break;
4667 e5febef5 ths
#ifdef TARGET_NR_waitpid
4668 31e31b8a bellard
    case TARGET_NR_waitpid:
4669 31e31b8a bellard
        {
4670 53a5960a pbrook
            int status;
4671 53a5960a pbrook
            ret = get_errno(waitpid(arg1, &status, arg3));
4672 2f619698 bellard
            if (!is_error(ret) && arg2
4673 1d9d8b55 pbrook
                && put_user_s32(host_to_target_waitstatus(status), arg2))
4674 2f619698 bellard
                goto efault;
4675 31e31b8a bellard
        }
4676 31e31b8a bellard
        break;
4677 e5febef5 ths
#endif
4678 f0cbb613 pbrook
#ifdef TARGET_NR_waitid
4679 f0cbb613 pbrook
    case TARGET_NR_waitid:
4680 f0cbb613 pbrook
        {
4681 f0cbb613 pbrook
            siginfo_t info;
4682 f0cbb613 pbrook
            info.si_pid = 0;
4683 f0cbb613 pbrook
            ret = get_errno(waitid(arg1, arg2, &info, arg4));
4684 f0cbb613 pbrook
            if (!is_error(ret) && arg3 && info.si_pid != 0) {
4685 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_siginfo_t), 0)))
4686 f0cbb613 pbrook
                    goto efault;
4687 f0cbb613 pbrook
                host_to_target_siginfo(p, &info);
4688 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_siginfo_t));
4689 f0cbb613 pbrook
            }
4690 f0cbb613 pbrook
        }
4691 f0cbb613 pbrook
        break;
4692 f0cbb613 pbrook
#endif
4693 7a3148a9 j_mayer
#ifdef TARGET_NR_creat /* not on alpha */
4694 31e31b8a bellard
    case TARGET_NR_creat:
4695 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4696 579a97f7 bellard
            goto efault;
4697 53a5960a pbrook
        ret = get_errno(creat(p, arg2));
4698 53a5960a pbrook
        unlock_user(p, arg1, 0);
4699 31e31b8a bellard
        break;
4700 7a3148a9 j_mayer
#endif
4701 31e31b8a bellard
    case TARGET_NR_link:
4702 53a5960a pbrook
        {
4703 53a5960a pbrook
            void * p2;
4704 53a5960a pbrook
            p = lock_user_string(arg1);
4705 53a5960a pbrook
            p2 = lock_user_string(arg2);
4706 579a97f7 bellard
            if (!p || !p2)
4707 579a97f7 bellard
                ret = -TARGET_EFAULT;
4708 579a97f7 bellard
            else
4709 579a97f7 bellard
                ret = get_errno(link(p, p2));
4710 53a5960a pbrook
            unlock_user(p2, arg2, 0);
4711 53a5960a pbrook
            unlock_user(p, arg1, 0);
4712 53a5960a pbrook
        }
4713 31e31b8a bellard
        break;
4714 64f0ce4c ths
#if defined(TARGET_NR_linkat) && defined(__NR_linkat)
4715 64f0ce4c ths
    case TARGET_NR_linkat:
4716 64f0ce4c ths
        {
4717 64f0ce4c ths
            void * p2 = NULL;
4718 579a97f7 bellard
            if (!arg2 || !arg4)
4719 579a97f7 bellard
                goto efault;
4720 64f0ce4c ths
            p  = lock_user_string(arg2);
4721 64f0ce4c ths
            p2 = lock_user_string(arg4);
4722 579a97f7 bellard
            if (!p || !p2)
4723 0da46a6e ths
                ret = -TARGET_EFAULT;
4724 64f0ce4c ths
            else
4725 64f0ce4c ths
                ret = get_errno(sys_linkat(arg1, p, arg3, p2, arg5));
4726 579a97f7 bellard
            unlock_user(p, arg2, 0);
4727 579a97f7 bellard
            unlock_user(p2, arg4, 0);
4728 64f0ce4c ths
        }
4729 64f0ce4c ths
        break;
4730 64f0ce4c ths
#endif
4731 31e31b8a bellard
    case TARGET_NR_unlink:
4732 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4733 579a97f7 bellard
            goto efault;
4734 53a5960a pbrook
        ret = get_errno(unlink(p));
4735 53a5960a pbrook
        unlock_user(p, arg1, 0);
4736 31e31b8a bellard
        break;
4737 8170f56b ths
#if defined(TARGET_NR_unlinkat) && defined(__NR_unlinkat)
4738 8170f56b ths
    case TARGET_NR_unlinkat:
4739 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4740 579a97f7 bellard
            goto efault;
4741 579a97f7 bellard
        ret = get_errno(sys_unlinkat(arg1, p, arg3));
4742 579a97f7 bellard
        unlock_user(p, arg2, 0);
4743 ed494d87 balrog
        break;
4744 b7d35e65 balrog
#endif
4745 31e31b8a bellard
    case TARGET_NR_execve:
4746 7854b056 bellard
        {
4747 7854b056 bellard
            char **argp, **envp;
4748 f7341ff4 bellard
            int argc, envc;
4749 992f48a0 blueswir1
            abi_ulong gp;
4750 992f48a0 blueswir1
            abi_ulong guest_argp;
4751 992f48a0 blueswir1
            abi_ulong guest_envp;
4752 992f48a0 blueswir1
            abi_ulong addr;
4753 7854b056 bellard
            char **q;
4754 7854b056 bellard
4755 f7341ff4 bellard
            argc = 0;
4756 53a5960a pbrook
            guest_argp = arg2;
4757 da94d263 pbrook
            for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) {
4758 03aa1976 ths
                if (get_user_ual(addr, gp))
4759 2f619698 bellard
                    goto efault;
4760 03aa1976 ths
                if (!addr)
4761 2f619698 bellard
                    break;
4762 7854b056 bellard
                argc++;
4763 2f619698 bellard
            }
4764 f7341ff4 bellard
            envc = 0;
4765 53a5960a pbrook
            guest_envp = arg3;
4766 da94d263 pbrook
            for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) {
4767 03aa1976 ths
                if (get_user_ual(addr, gp))
4768 2f619698 bellard
                    goto efault;
4769 03aa1976 ths
                if (!addr)
4770 2f619698 bellard
                    break;
4771 7854b056 bellard
                envc++;
4772 2f619698 bellard
            }
4773 7854b056 bellard
4774 f7341ff4 bellard
            argp = alloca((argc + 1) * sizeof(void *));
4775 f7341ff4 bellard
            envp = alloca((envc + 1) * sizeof(void *));
4776 7854b056 bellard
4777 da94d263 pbrook
            for (gp = guest_argp, q = argp; gp;
4778 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4779 2f619698 bellard
                if (get_user_ual(addr, gp))
4780 2f619698 bellard
                    goto execve_efault;
4781 53a5960a pbrook
                if (!addr)
4782 53a5960a pbrook
                    break;
4783 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
4784 2f619698 bellard
                    goto execve_efault;
4785 53a5960a pbrook
            }
4786 f7341ff4 bellard
            *q = NULL;
4787 f7341ff4 bellard
4788 da94d263 pbrook
            for (gp = guest_envp, q = envp; gp;
4789 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4790 2f619698 bellard
                if (get_user_ual(addr, gp))
4791 2f619698 bellard
                    goto execve_efault;
4792 53a5960a pbrook
                if (!addr)
4793 53a5960a pbrook
                    break;
4794 2f619698 bellard
                if (!(*q = lock_user_string(addr)))
4795 2f619698 bellard
                    goto execve_efault;
4796 53a5960a pbrook
            }
4797 f7341ff4 bellard
            *q = NULL;
4798 7854b056 bellard
4799 2f619698 bellard
            if (!(p = lock_user_string(arg1)))
4800 2f619698 bellard
                goto execve_efault;
4801 53a5960a pbrook
            ret = get_errno(execve(p, argp, envp));
4802 53a5960a pbrook
            unlock_user(p, arg1, 0);
4803 53a5960a pbrook
4804 2f619698 bellard
            goto execve_end;
4805 2f619698 bellard
4806 2f619698 bellard
        execve_efault:
4807 2f619698 bellard
            ret = -TARGET_EFAULT;
4808 2f619698 bellard
4809 2f619698 bellard
        execve_end:
4810 53a5960a pbrook
            for (gp = guest_argp, q = argp; *q;
4811 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4812 2f619698 bellard
                if (get_user_ual(addr, gp)
4813 2f619698 bellard
                    || !addr)
4814 2f619698 bellard
                    break;
4815 53a5960a pbrook
                unlock_user(*q, addr, 0);
4816 53a5960a pbrook
            }
4817 53a5960a pbrook
            for (gp = guest_envp, q = envp; *q;
4818 992f48a0 blueswir1
                  gp += sizeof(abi_ulong), q++) {
4819 2f619698 bellard
                if (get_user_ual(addr, gp)
4820 2f619698 bellard
                    || !addr)
4821 2f619698 bellard
                    break;
4822 53a5960a pbrook
                unlock_user(*q, addr, 0);
4823 53a5960a pbrook
            }
4824 7854b056 bellard
        }
4825 31e31b8a bellard
        break;
4826 31e31b8a bellard
    case TARGET_NR_chdir:
4827 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4828 579a97f7 bellard
            goto efault;
4829 53a5960a pbrook
        ret = get_errno(chdir(p));
4830 53a5960a pbrook
        unlock_user(p, arg1, 0);
4831 31e31b8a bellard
        break;
4832 a315a145 bellard
#ifdef TARGET_NR_time
4833 31e31b8a bellard
    case TARGET_NR_time:
4834 31e31b8a bellard
        {
4835 53a5960a pbrook
            time_t host_time;
4836 53a5960a pbrook
            ret = get_errno(time(&host_time));
4837 2f619698 bellard
            if (!is_error(ret)
4838 2f619698 bellard
                && arg1
4839 2f619698 bellard
                && put_user_sal(host_time, arg1))
4840 2f619698 bellard
                goto efault;
4841 31e31b8a bellard
        }
4842 31e31b8a bellard
        break;
4843 a315a145 bellard
#endif
4844 31e31b8a bellard
    case TARGET_NR_mknod:
4845 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4846 579a97f7 bellard
            goto efault;
4847 53a5960a pbrook
        ret = get_errno(mknod(p, arg2, arg3));
4848 53a5960a pbrook
        unlock_user(p, arg1, 0);
4849 31e31b8a bellard
        break;
4850 75ac37a0 ths
#if defined(TARGET_NR_mknodat) && defined(__NR_mknodat)
4851 75ac37a0 ths
    case TARGET_NR_mknodat:
4852 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
4853 579a97f7 bellard
            goto efault;
4854 579a97f7 bellard
        ret = get_errno(sys_mknodat(arg1, p, arg3, arg4));
4855 579a97f7 bellard
        unlock_user(p, arg2, 0);
4856 75ac37a0 ths
        break;
4857 75ac37a0 ths
#endif
4858 31e31b8a bellard
    case TARGET_NR_chmod:
4859 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4860 579a97f7 bellard
            goto efault;
4861 53a5960a pbrook
        ret = get_errno(chmod(p, arg2));
4862 53a5960a pbrook
        unlock_user(p, arg1, 0);
4863 31e31b8a bellard
        break;
4864 ebc05488 bellard
#ifdef TARGET_NR_break
4865 31e31b8a bellard
    case TARGET_NR_break:
4866 31e31b8a bellard
        goto unimplemented;
4867 ebc05488 bellard
#endif
4868 ebc05488 bellard
#ifdef TARGET_NR_oldstat
4869 31e31b8a bellard
    case TARGET_NR_oldstat:
4870 31e31b8a bellard
        goto unimplemented;
4871 ebc05488 bellard
#endif
4872 31e31b8a bellard
    case TARGET_NR_lseek:
4873 31e31b8a bellard
        ret = get_errno(lseek(arg1, arg2, arg3));
4874 31e31b8a bellard
        break;
4875 9231733a Richard Henderson
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
4876 9231733a Richard Henderson
    /* Alpha specific */
4877 7a3148a9 j_mayer
    case TARGET_NR_getxpid:
4878 9231733a Richard Henderson
        ((CPUAlphaState *)cpu_env)->ir[IR_A4] = getppid();
4879 9231733a Richard Henderson
        ret = get_errno(getpid());
4880 9231733a Richard Henderson
        break;
4881 7a3148a9 j_mayer
#endif
4882 9231733a Richard Henderson
#ifdef TARGET_NR_getpid
4883 9231733a Richard Henderson
    case TARGET_NR_getpid:
4884 31e31b8a bellard
        ret = get_errno(getpid());
4885 31e31b8a bellard
        break;
4886 9231733a Richard Henderson
#endif
4887 31e31b8a bellard
    case TARGET_NR_mount:
4888 80265918 ths
                {
4889 80265918 ths
                        /* need to look at the data field */
4890 80265918 ths
                        void *p2, *p3;
4891 80265918 ths
                        p = lock_user_string(arg1);
4892 80265918 ths
                        p2 = lock_user_string(arg2);
4893 80265918 ths
                        p3 = lock_user_string(arg3);
4894 579a97f7 bellard
                        if (!p || !p2 || !p3)
4895 579a97f7 bellard
                            ret = -TARGET_EFAULT;
4896 dab46405 Jan-Simon Möller
                        else {
4897 579a97f7 bellard
                            /* FIXME - arg5 should be locked, but it isn't clear how to
4898 579a97f7 bellard
                             * do that since it's not guaranteed to be a NULL-terminated
4899 579a97f7 bellard
                             * string.
4900 579a97f7 bellard
                             */
4901 dab46405 Jan-Simon Möller
                            if ( ! arg5 )
4902 dab46405 Jan-Simon Möller
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, NULL));
4903 dab46405 Jan-Simon Möller
                            else
4904 dab46405 Jan-Simon Möller
                                ret = get_errno(mount(p, p2, p3, (unsigned long)arg4, g2h(arg5)));
4905 dab46405 Jan-Simon Möller
                        }
4906 579a97f7 bellard
                        unlock_user(p, arg1, 0);
4907 579a97f7 bellard
                        unlock_user(p2, arg2, 0);
4908 579a97f7 bellard
                        unlock_user(p3, arg3, 0);
4909 80265918 ths
                        break;
4910 80265918 ths
                }
4911 e5febef5 ths
#ifdef TARGET_NR_umount
4912 31e31b8a bellard
    case TARGET_NR_umount:
4913 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
4914 579a97f7 bellard
            goto efault;
4915 53a5960a pbrook
        ret = get_errno(umount(p));
4916 53a5960a pbrook
        unlock_user(p, arg1, 0);
4917 31e31b8a bellard
        break;
4918 e5febef5 ths
#endif
4919 7a3148a9 j_mayer
#ifdef TARGET_NR_stime /* not on alpha */
4920 31e31b8a bellard
    case TARGET_NR_stime:
4921 31e31b8a bellard
        {
4922 53a5960a pbrook
            time_t host_time;
4923 2f619698 bellard
            if (get_user_sal(host_time, arg1))
4924 2f619698 bellard
                goto efault;
4925 53a5960a pbrook
            ret = get_errno(stime(&host_time));
4926 31e31b8a bellard
        }
4927 31e31b8a bellard
        break;
4928 7a3148a9 j_mayer
#endif
4929 31e31b8a bellard
    case TARGET_NR_ptrace:
4930 31e31b8a bellard
        goto unimplemented;
4931 7a3148a9 j_mayer
#ifdef TARGET_NR_alarm /* not on alpha */
4932 31e31b8a bellard
    case TARGET_NR_alarm:
4933 31e31b8a bellard
        ret = alarm(arg1);
4934 31e31b8a bellard
        break;
4935 7a3148a9 j_mayer
#endif
4936 ebc05488 bellard
#ifdef TARGET_NR_oldfstat
4937 31e31b8a bellard
    case TARGET_NR_oldfstat:
4938 31e31b8a bellard
        goto unimplemented;
4939 ebc05488 bellard
#endif
4940 7a3148a9 j_mayer
#ifdef TARGET_NR_pause /* not on alpha */
4941 31e31b8a bellard
    case TARGET_NR_pause:
4942 31e31b8a bellard
        ret = get_errno(pause());
4943 31e31b8a bellard
        break;
4944 7a3148a9 j_mayer
#endif
4945 e5febef5 ths
#ifdef TARGET_NR_utime
4946 31e31b8a bellard
    case TARGET_NR_utime:
4947 ebc05488 bellard
        {
4948 53a5960a pbrook
            struct utimbuf tbuf, *host_tbuf;
4949 53a5960a pbrook
            struct target_utimbuf *target_tbuf;
4950 53a5960a pbrook
            if (arg2) {
4951 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, target_tbuf, arg2, 1))
4952 579a97f7 bellard
                    goto efault;
4953 53a5960a pbrook
                tbuf.actime = tswapl(target_tbuf->actime);
4954 53a5960a pbrook
                tbuf.modtime = tswapl(target_tbuf->modtime);
4955 53a5960a pbrook
                unlock_user_struct(target_tbuf, arg2, 0);
4956 53a5960a pbrook
                host_tbuf = &tbuf;
4957 f72e8ff4 bellard
            } else {
4958 53a5960a pbrook
                host_tbuf = NULL;
4959 f72e8ff4 bellard
            }
4960 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
4961 579a97f7 bellard
                goto efault;
4962 53a5960a pbrook
            ret = get_errno(utime(p, host_tbuf));
4963 53a5960a pbrook
            unlock_user(p, arg1, 0);
4964 ebc05488 bellard
        }
4965 ebc05488 bellard
        break;
4966 e5febef5 ths
#endif
4967 978a66ff bellard
    case TARGET_NR_utimes:
4968 978a66ff bellard
        {
4969 978a66ff bellard
            struct timeval *tvp, tv[2];
4970 53a5960a pbrook
            if (arg2) {
4971 788f5ec4 ths
                if (copy_from_user_timeval(&tv[0], arg2)
4972 788f5ec4 ths
                    || copy_from_user_timeval(&tv[1],
4973 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
4974 788f5ec4 ths
                    goto efault;
4975 978a66ff bellard
                tvp = tv;
4976 978a66ff bellard
            } else {
4977 978a66ff bellard
                tvp = NULL;
4978 978a66ff bellard
            }
4979 579a97f7 bellard
            if (!(p = lock_user_string(arg1)))
4980 579a97f7 bellard
                goto efault;
4981 53a5960a pbrook
            ret = get_errno(utimes(p, tvp));
4982 53a5960a pbrook
            unlock_user(p, arg1, 0);
4983 978a66ff bellard
        }
4984 978a66ff bellard
        break;
4985 ac8a6556 balrog
#if defined(TARGET_NR_futimesat) && defined(__NR_futimesat)
4986 ac8a6556 balrog
    case TARGET_NR_futimesat:
4987 ac8a6556 balrog
        {
4988 ac8a6556 balrog
            struct timeval *tvp, tv[2];
4989 ac8a6556 balrog
            if (arg3) {
4990 ac8a6556 balrog
                if (copy_from_user_timeval(&tv[0], arg3)
4991 ac8a6556 balrog
                    || copy_from_user_timeval(&tv[1],
4992 ac8a6556 balrog
                                              arg3 + sizeof(struct target_timeval)))
4993 ac8a6556 balrog
                    goto efault;
4994 ac8a6556 balrog
                tvp = tv;
4995 ac8a6556 balrog
            } else {
4996 ac8a6556 balrog
                tvp = NULL;
4997 ac8a6556 balrog
            }
4998 ac8a6556 balrog
            if (!(p = lock_user_string(arg2)))
4999 ac8a6556 balrog
                goto efault;
5000 ac8a6556 balrog
            ret = get_errno(sys_futimesat(arg1, path(p), tvp));
5001 ac8a6556 balrog
            unlock_user(p, arg2, 0);
5002 ac8a6556 balrog
        }
5003 ac8a6556 balrog
        break;
5004 ac8a6556 balrog
#endif
5005 ebc05488 bellard
#ifdef TARGET_NR_stty
5006 31e31b8a bellard
    case TARGET_NR_stty:
5007 31e31b8a bellard
        goto unimplemented;
5008 ebc05488 bellard
#endif
5009 ebc05488 bellard
#ifdef TARGET_NR_gtty
5010 31e31b8a bellard
    case TARGET_NR_gtty:
5011 31e31b8a bellard
        goto unimplemented;
5012 ebc05488 bellard
#endif
5013 31e31b8a bellard
    case TARGET_NR_access:
5014 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5015 579a97f7 bellard
            goto efault;
5016 719f908e Ulrich Hecht
        ret = get_errno(access(path(p), arg2));
5017 53a5960a pbrook
        unlock_user(p, arg1, 0);
5018 31e31b8a bellard
        break;
5019 92a34c10 ths
#if defined(TARGET_NR_faccessat) && defined(__NR_faccessat)
5020 92a34c10 ths
    case TARGET_NR_faccessat:
5021 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
5022 579a97f7 bellard
            goto efault;
5023 465c9f06 aurel32
        ret = get_errno(sys_faccessat(arg1, p, arg3));
5024 579a97f7 bellard
        unlock_user(p, arg2, 0);
5025 92a34c10 ths
        break;
5026 92a34c10 ths
#endif
5027 7a3148a9 j_mayer
#ifdef TARGET_NR_nice /* not on alpha */
5028 31e31b8a bellard
    case TARGET_NR_nice:
5029 31e31b8a bellard
        ret = get_errno(nice(arg1));
5030 31e31b8a bellard
        break;
5031 7a3148a9 j_mayer
#endif
5032 ebc05488 bellard
#ifdef TARGET_NR_ftime
5033 31e31b8a bellard
    case TARGET_NR_ftime:
5034 31e31b8a bellard
        goto unimplemented;
5035 ebc05488 bellard
#endif
5036 31e31b8a bellard
    case TARGET_NR_sync:
5037 04369ff2 bellard
        sync();
5038 04369ff2 bellard
        ret = 0;
5039 31e31b8a bellard
        break;
5040 31e31b8a bellard
    case TARGET_NR_kill:
5041 4cb05961 pbrook
        ret = get_errno(kill(arg1, target_to_host_signal(arg2)));
5042 31e31b8a bellard
        break;
5043 31e31b8a bellard
    case TARGET_NR_rename:
5044 53a5960a pbrook
        {
5045 53a5960a pbrook
            void *p2;
5046 53a5960a pbrook
            p = lock_user_string(arg1);
5047 53a5960a pbrook
            p2 = lock_user_string(arg2);
5048 579a97f7 bellard
            if (!p || !p2)
5049 579a97f7 bellard
                ret = -TARGET_EFAULT;
5050 579a97f7 bellard
            else
5051 579a97f7 bellard
                ret = get_errno(rename(p, p2));
5052 53a5960a pbrook
            unlock_user(p2, arg2, 0);
5053 53a5960a pbrook
            unlock_user(p, arg1, 0);
5054 53a5960a pbrook
        }
5055 31e31b8a bellard
        break;
5056 722183f6 ths
#if defined(TARGET_NR_renameat) && defined(__NR_renameat)
5057 722183f6 ths
    case TARGET_NR_renameat:
5058 722183f6 ths
        {
5059 579a97f7 bellard
            void *p2;
5060 722183f6 ths
            p  = lock_user_string(arg2);
5061 722183f6 ths
            p2 = lock_user_string(arg4);
5062 579a97f7 bellard
            if (!p || !p2)
5063 0da46a6e ths
                ret = -TARGET_EFAULT;
5064 722183f6 ths
            else
5065 722183f6 ths
                ret = get_errno(sys_renameat(arg1, p, arg3, p2));
5066 579a97f7 bellard
            unlock_user(p2, arg4, 0);
5067 579a97f7 bellard
            unlock_user(p, arg2, 0);
5068 722183f6 ths
        }
5069 722183f6 ths
        break;
5070 722183f6 ths
#endif
5071 31e31b8a bellard
    case TARGET_NR_mkdir:
5072 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5073 579a97f7 bellard
            goto efault;
5074 53a5960a pbrook
        ret = get_errno(mkdir(p, arg2));
5075 53a5960a pbrook
        unlock_user(p, arg1, 0);
5076 31e31b8a bellard
        break;
5077 4472ad0d ths
#if defined(TARGET_NR_mkdirat) && defined(__NR_mkdirat)
5078 4472ad0d ths
    case TARGET_NR_mkdirat:
5079 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
5080 579a97f7 bellard
            goto efault;
5081 579a97f7 bellard
        ret = get_errno(sys_mkdirat(arg1, p, arg3));
5082 579a97f7 bellard
        unlock_user(p, arg2, 0);
5083 4472ad0d ths
        break;
5084 4472ad0d ths
#endif
5085 31e31b8a bellard
    case TARGET_NR_rmdir:
5086 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5087 579a97f7 bellard
            goto efault;
5088 53a5960a pbrook
        ret = get_errno(rmdir(p));
5089 53a5960a pbrook
        unlock_user(p, arg1, 0);
5090 31e31b8a bellard
        break;
5091 31e31b8a bellard
    case TARGET_NR_dup:
5092 31e31b8a bellard
        ret = get_errno(dup(arg1));
5093 31e31b8a bellard
        break;
5094 31e31b8a bellard
    case TARGET_NR_pipe:
5095 fb41a66e Richard Henderson
        ret = do_pipe(cpu_env, arg1, 0, 0);
5096 099d6b0f Riku Voipio
        break;
5097 099d6b0f Riku Voipio
#ifdef TARGET_NR_pipe2
5098 099d6b0f Riku Voipio
    case TARGET_NR_pipe2:
5099 fb41a66e Richard Henderson
        ret = do_pipe(cpu_env, arg1, arg2, 1);
5100 31e31b8a bellard
        break;
5101 099d6b0f Riku Voipio
#endif
5102 31e31b8a bellard
    case TARGET_NR_times:
5103 32f36bce bellard
        {
5104 53a5960a pbrook
            struct target_tms *tmsp;
5105 32f36bce bellard
            struct tms tms;
5106 32f36bce bellard
            ret = get_errno(times(&tms));
5107 53a5960a pbrook
            if (arg1) {
5108 579a97f7 bellard
                tmsp = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_tms), 0);
5109 579a97f7 bellard
                if (!tmsp)
5110 579a97f7 bellard
                    goto efault;
5111 c596ed17 bellard
                tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
5112 c596ed17 bellard
                tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
5113 c596ed17 bellard
                tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
5114 c596ed17 bellard
                tmsp->tms_cstime = tswapl(host_to_target_clock_t(tms.tms_cstime));
5115 32f36bce bellard
            }
5116 c596ed17 bellard
            if (!is_error(ret))
5117 c596ed17 bellard
                ret = host_to_target_clock_t(ret);
5118 32f36bce bellard
        }
5119 32f36bce bellard
        break;
5120 ebc05488 bellard
#ifdef TARGET_NR_prof
5121 31e31b8a bellard
    case TARGET_NR_prof:
5122 31e31b8a bellard
        goto unimplemented;
5123 ebc05488 bellard
#endif
5124 e5febef5 ths
#ifdef TARGET_NR_signal
5125 31e31b8a bellard
    case TARGET_NR_signal:
5126 31e31b8a bellard
        goto unimplemented;
5127 e5febef5 ths
#endif
5128 31e31b8a bellard
    case TARGET_NR_acct:
5129 38d840e6 aurel32
        if (arg1 == 0) {
5130 38d840e6 aurel32
            ret = get_errno(acct(NULL));
5131 38d840e6 aurel32
        } else {
5132 38d840e6 aurel32
            if (!(p = lock_user_string(arg1)))
5133 38d840e6 aurel32
                goto efault;
5134 38d840e6 aurel32
            ret = get_errno(acct(path(p)));
5135 38d840e6 aurel32
            unlock_user(p, arg1, 0);
5136 38d840e6 aurel32
        }
5137 24836689 pbrook
        break;
5138 7a3148a9 j_mayer
#ifdef TARGET_NR_umount2 /* not on alpha */
5139 31e31b8a bellard
    case TARGET_NR_umount2:
5140 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5141 579a97f7 bellard
            goto efault;
5142 53a5960a pbrook
        ret = get_errno(umount2(p, arg2));
5143 53a5960a pbrook
        unlock_user(p, arg1, 0);
5144 31e31b8a bellard
        break;
5145 7a3148a9 j_mayer
#endif
5146 ebc05488 bellard
#ifdef TARGET_NR_lock
5147 31e31b8a bellard
    case TARGET_NR_lock:
5148 31e31b8a bellard
        goto unimplemented;
5149 ebc05488 bellard
#endif
5150 31e31b8a bellard
    case TARGET_NR_ioctl:
5151 31e31b8a bellard
        ret = do_ioctl(arg1, arg2, arg3);
5152 31e31b8a bellard
        break;
5153 31e31b8a bellard
    case TARGET_NR_fcntl:
5154 9ee1fa2c bellard
        ret = do_fcntl(arg1, arg2, arg3);
5155 31e31b8a bellard
        break;
5156 ebc05488 bellard
#ifdef TARGET_NR_mpx
5157 31e31b8a bellard
    case TARGET_NR_mpx:
5158 31e31b8a bellard
        goto unimplemented;
5159 ebc05488 bellard
#endif
5160 31e31b8a bellard
    case TARGET_NR_setpgid:
5161 31e31b8a bellard
        ret = get_errno(setpgid(arg1, arg2));
5162 31e31b8a bellard
        break;
5163 ebc05488 bellard
#ifdef TARGET_NR_ulimit
5164 31e31b8a bellard
    case TARGET_NR_ulimit:
5165 31e31b8a bellard
        goto unimplemented;
5166 ebc05488 bellard
#endif
5167 ebc05488 bellard
#ifdef TARGET_NR_oldolduname
5168 31e31b8a bellard
    case TARGET_NR_oldolduname:
5169 31e31b8a bellard
        goto unimplemented;
5170 ebc05488 bellard
#endif
5171 31e31b8a bellard
    case TARGET_NR_umask:
5172 31e31b8a bellard
        ret = get_errno(umask(arg1));
5173 31e31b8a bellard
        break;
5174 31e31b8a bellard
    case TARGET_NR_chroot:
5175 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5176 579a97f7 bellard
            goto efault;
5177 53a5960a pbrook
        ret = get_errno(chroot(p));
5178 53a5960a pbrook
        unlock_user(p, arg1, 0);
5179 31e31b8a bellard
        break;
5180 31e31b8a bellard
    case TARGET_NR_ustat:
5181 31e31b8a bellard
        goto unimplemented;
5182 31e31b8a bellard
    case TARGET_NR_dup2:
5183 31e31b8a bellard
        ret = get_errno(dup2(arg1, arg2));
5184 31e31b8a bellard
        break;
5185 d0927938 Ulrich Hecht
#if defined(CONFIG_DUP3) && defined(TARGET_NR_dup3)
5186 d0927938 Ulrich Hecht
    case TARGET_NR_dup3:
5187 d0927938 Ulrich Hecht
        ret = get_errno(dup3(arg1, arg2, arg3));
5188 d0927938 Ulrich Hecht
        break;
5189 d0927938 Ulrich Hecht
#endif
5190 7a3148a9 j_mayer
#ifdef TARGET_NR_getppid /* not on alpha */
5191 31e31b8a bellard
    case TARGET_NR_getppid:
5192 31e31b8a bellard
        ret = get_errno(getppid());
5193 31e31b8a bellard
        break;
5194 7a3148a9 j_mayer
#endif
5195 31e31b8a bellard
    case TARGET_NR_getpgrp:
5196 31e31b8a bellard
        ret = get_errno(getpgrp());
5197 31e31b8a bellard
        break;
5198 31e31b8a bellard
    case TARGET_NR_setsid:
5199 31e31b8a bellard
        ret = get_errno(setsid());
5200 31e31b8a bellard
        break;
5201 e5febef5 ths
#ifdef TARGET_NR_sigaction
5202 31e31b8a bellard
    case TARGET_NR_sigaction:
5203 31e31b8a bellard
        {
5204 6049f4f8 Richard Henderson
#if defined(TARGET_ALPHA)
5205 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact = 0;
5206 53a5960a pbrook
            struct target_old_sigaction *old_act;
5207 53a5960a pbrook
            if (arg2) {
5208 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5209 579a97f7 bellard
                    goto efault;
5210 66fb9763 bellard
                act._sa_handler = old_act->_sa_handler;
5211 66fb9763 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5212 66fb9763 bellard
                act.sa_flags = old_act->sa_flags;
5213 6049f4f8 Richard Henderson
                act.sa_restorer = 0;
5214 53a5960a pbrook
                unlock_user_struct(old_act, arg2, 0);
5215 66fb9763 bellard
                pact = &act;
5216 66fb9763 bellard
            }
5217 66fb9763 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5218 53a5960a pbrook
            if (!is_error(ret) && arg3) {
5219 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5220 579a97f7 bellard
                    goto efault;
5221 53a5960a pbrook
                old_act->_sa_handler = oact._sa_handler;
5222 53a5960a pbrook
                old_act->sa_mask = oact.sa_mask.sig[0];
5223 53a5960a pbrook
                old_act->sa_flags = oact.sa_flags;
5224 53a5960a pbrook
                unlock_user_struct(old_act, arg3, 1);
5225 66fb9763 bellard
            }
5226 6049f4f8 Richard Henderson
#elif defined(TARGET_MIPS)
5227 106ec879 bellard
            struct target_sigaction act, oact, *pact, *old_act;
5228 106ec879 bellard
5229 106ec879 bellard
            if (arg2) {
5230 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5231 579a97f7 bellard
                    goto efault;
5232 106ec879 bellard
                act._sa_handler = old_act->_sa_handler;
5233 106ec879 bellard
                target_siginitset(&act.sa_mask, old_act->sa_mask.sig[0]);
5234 106ec879 bellard
                act.sa_flags = old_act->sa_flags;
5235 106ec879 bellard
                unlock_user_struct(old_act, arg2, 0);
5236 106ec879 bellard
                pact = &act;
5237 106ec879 bellard
            } else {
5238 106ec879 bellard
                pact = NULL;
5239 106ec879 bellard
            }
5240 106ec879 bellard
5241 106ec879 bellard
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5242 106ec879 bellard
5243 106ec879 bellard
            if (!is_error(ret) && arg3) {
5244 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5245 579a97f7 bellard
                    goto efault;
5246 106ec879 bellard
                old_act->_sa_handler = oact._sa_handler;
5247 106ec879 bellard
                old_act->sa_flags = oact.sa_flags;
5248 106ec879 bellard
                old_act->sa_mask.sig[0] = oact.sa_mask.sig[0];
5249 106ec879 bellard
                old_act->sa_mask.sig[1] = 0;
5250 106ec879 bellard
                old_act->sa_mask.sig[2] = 0;
5251 106ec879 bellard
                old_act->sa_mask.sig[3] = 0;
5252 106ec879 bellard
                unlock_user_struct(old_act, arg3, 1);
5253 106ec879 bellard
            }
5254 6049f4f8 Richard Henderson
#else
5255 6049f4f8 Richard Henderson
            struct target_old_sigaction *old_act;
5256 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact;
5257 6049f4f8 Richard Henderson
            if (arg2) {
5258 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
5259 6049f4f8 Richard Henderson
                    goto efault;
5260 6049f4f8 Richard Henderson
                act._sa_handler = old_act->_sa_handler;
5261 6049f4f8 Richard Henderson
                target_siginitset(&act.sa_mask, old_act->sa_mask);
5262 6049f4f8 Richard Henderson
                act.sa_flags = old_act->sa_flags;
5263 6049f4f8 Richard Henderson
                act.sa_restorer = old_act->sa_restorer;
5264 6049f4f8 Richard Henderson
                unlock_user_struct(old_act, arg2, 0);
5265 6049f4f8 Richard Henderson
                pact = &act;
5266 6049f4f8 Richard Henderson
            } else {
5267 6049f4f8 Richard Henderson
                pact = NULL;
5268 6049f4f8 Richard Henderson
            }
5269 6049f4f8 Richard Henderson
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5270 6049f4f8 Richard Henderson
            if (!is_error(ret) && arg3) {
5271 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
5272 6049f4f8 Richard Henderson
                    goto efault;
5273 6049f4f8 Richard Henderson
                old_act->_sa_handler = oact._sa_handler;
5274 6049f4f8 Richard Henderson
                old_act->sa_mask = oact.sa_mask.sig[0];
5275 6049f4f8 Richard Henderson
                old_act->sa_flags = oact.sa_flags;
5276 6049f4f8 Richard Henderson
                old_act->sa_restorer = oact.sa_restorer;
5277 6049f4f8 Richard Henderson
                unlock_user_struct(old_act, arg3, 1);
5278 6049f4f8 Richard Henderson
            }
5279 388bb21a ths
#endif
5280 31e31b8a bellard
        }
5281 31e31b8a bellard
        break;
5282 e5febef5 ths
#endif
5283 66fb9763 bellard
    case TARGET_NR_rt_sigaction:
5284 53a5960a pbrook
        {
5285 6049f4f8 Richard Henderson
#if defined(TARGET_ALPHA)
5286 6049f4f8 Richard Henderson
            struct target_sigaction act, oact, *pact = 0;
5287 6049f4f8 Richard Henderson
            struct target_rt_sigaction *rt_act;
5288 6049f4f8 Richard Henderson
            /* ??? arg4 == sizeof(sigset_t).  */
5289 6049f4f8 Richard Henderson
            if (arg2) {
5290 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
5291 6049f4f8 Richard Henderson
                    goto efault;
5292 6049f4f8 Richard Henderson
                act._sa_handler = rt_act->_sa_handler;
5293 6049f4f8 Richard Henderson
                act.sa_mask = rt_act->sa_mask;
5294 6049f4f8 Richard Henderson
                act.sa_flags = rt_act->sa_flags;
5295 6049f4f8 Richard Henderson
                act.sa_restorer = arg5;
5296 6049f4f8 Richard Henderson
                unlock_user_struct(rt_act, arg2, 0);
5297 6049f4f8 Richard Henderson
                pact = &act;
5298 6049f4f8 Richard Henderson
            }
5299 6049f4f8 Richard Henderson
            ret = get_errno(do_sigaction(arg1, pact, &oact));
5300 6049f4f8 Richard Henderson
            if (!is_error(ret) && arg3) {
5301 6049f4f8 Richard Henderson
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
5302 6049f4f8 Richard Henderson
                    goto efault;
5303 6049f4f8 Richard Henderson
                rt_act->_sa_handler = oact._sa_handler;
5304 6049f4f8 Richard Henderson
                rt_act->sa_mask = oact.sa_mask;
5305 6049f4f8 Richard Henderson
                rt_act->sa_flags = oact.sa_flags;
5306 6049f4f8 Richard Henderson
                unlock_user_struct(rt_act, arg3, 1);
5307 6049f4f8 Richard Henderson
            }
5308 6049f4f8 Richard Henderson
#else
5309 53a5960a pbrook
            struct target_sigaction *act;
5310 53a5960a pbrook
            struct target_sigaction *oact;
5311 53a5960a pbrook
5312 579a97f7 bellard
            if (arg2) {
5313 579a97f7 bellard
                if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
5314 579a97f7 bellard
                    goto efault;
5315 579a97f7 bellard
            } else
5316 53a5960a pbrook
                act = NULL;
5317 579a97f7 bellard
            if (arg3) {
5318 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
5319 579a97f7 bellard
                    ret = -TARGET_EFAULT;
5320 579a97f7 bellard
                    goto rt_sigaction_fail;
5321 579a97f7 bellard
                }
5322 579a97f7 bellard
            } else
5323 53a5960a pbrook
                oact = NULL;
5324 53a5960a pbrook
            ret = get_errno(do_sigaction(arg1, act, oact));
5325 579a97f7 bellard
        rt_sigaction_fail:
5326 579a97f7 bellard
            if (act)
5327 53a5960a pbrook
                unlock_user_struct(act, arg2, 0);
5328 579a97f7 bellard
            if (oact)
5329 53a5960a pbrook
                unlock_user_struct(oact, arg3, 1);
5330 6049f4f8 Richard Henderson
#endif
5331 53a5960a pbrook
        }
5332 66fb9763 bellard
        break;
5333 7a3148a9 j_mayer
#ifdef TARGET_NR_sgetmask /* not on alpha */
5334 31e31b8a bellard
    case TARGET_NR_sgetmask:
5335 66fb9763 bellard
        {
5336 66fb9763 bellard
            sigset_t cur_set;
5337 992f48a0 blueswir1
            abi_ulong target_set;
5338 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
5339 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &cur_set);
5340 66fb9763 bellard
            ret = target_set;
5341 66fb9763 bellard
        }
5342 66fb9763 bellard
        break;
5343 7a3148a9 j_mayer
#endif
5344 7a3148a9 j_mayer
#ifdef TARGET_NR_ssetmask /* not on alpha */
5345 31e31b8a bellard
    case TARGET_NR_ssetmask:
5346 66fb9763 bellard
        {
5347 66fb9763 bellard
            sigset_t set, oset, cur_set;
5348 992f48a0 blueswir1
            abi_ulong target_set = arg1;
5349 66fb9763 bellard
            sigprocmask(0, NULL, &cur_set);
5350 66fb9763 bellard
            target_to_host_old_sigset(&set, &target_set);
5351 66fb9763 bellard
            sigorset(&set, &set, &cur_set);
5352 66fb9763 bellard
            sigprocmask(SIG_SETMASK, &set, &oset);
5353 66fb9763 bellard
            host_to_target_old_sigset(&target_set, &oset);
5354 66fb9763 bellard
            ret = target_set;
5355 66fb9763 bellard
        }
5356 66fb9763 bellard
        break;
5357 7a3148a9 j_mayer
#endif
5358 e5febef5 ths
#ifdef TARGET_NR_sigprocmask
5359 66fb9763 bellard
    case TARGET_NR_sigprocmask:
5360 66fb9763 bellard
        {
5361 a5b3b13b Richard Henderson
#if defined(TARGET_ALPHA)
5362 a5b3b13b Richard Henderson
            sigset_t set, oldset;
5363 a5b3b13b Richard Henderson
            abi_ulong mask;
5364 a5b3b13b Richard Henderson
            int how;
5365 a5b3b13b Richard Henderson
5366 a5b3b13b Richard Henderson
            switch (arg1) {
5367 a5b3b13b Richard Henderson
            case TARGET_SIG_BLOCK:
5368 a5b3b13b Richard Henderson
                how = SIG_BLOCK;
5369 a5b3b13b Richard Henderson
                break;
5370 a5b3b13b Richard Henderson
            case TARGET_SIG_UNBLOCK:
5371 a5b3b13b Richard Henderson
                how = SIG_UNBLOCK;
5372 a5b3b13b Richard Henderson
                break;
5373 a5b3b13b Richard Henderson
            case TARGET_SIG_SETMASK:
5374 a5b3b13b Richard Henderson
                how = SIG_SETMASK;
5375 a5b3b13b Richard Henderson
                break;
5376 a5b3b13b Richard Henderson
            default:
5377 a5b3b13b Richard Henderson
                ret = -TARGET_EINVAL;
5378 a5b3b13b Richard Henderson
                goto fail;
5379 a5b3b13b Richard Henderson
            }
5380 a5b3b13b Richard Henderson
            mask = arg2;
5381 a5b3b13b Richard Henderson
            target_to_host_old_sigset(&set, &mask);
5382 a5b3b13b Richard Henderson
5383 a5b3b13b Richard Henderson
            ret = get_errno(sigprocmask(how, &set, &oldset));
5384 a5b3b13b Richard Henderson
5385 a5b3b13b Richard Henderson
            if (!is_error(ret)) {
5386 a5b3b13b Richard Henderson
                host_to_target_old_sigset(&mask, &oldset);
5387 a5b3b13b Richard Henderson
                ret = mask;
5388 a5b3b13b Richard Henderson
                ((CPUAlphaState *)cpu_env)->[IR_V0] = 0; /* force no error */
5389 a5b3b13b Richard Henderson
            }
5390 a5b3b13b Richard Henderson
#else
5391 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
5392 a5b3b13b Richard Henderson
            int how;
5393 3b46e624 ths
5394 53a5960a pbrook
            if (arg2) {
5395 a5b3b13b Richard Henderson
                switch (arg1) {
5396 66fb9763 bellard
                case TARGET_SIG_BLOCK:
5397 66fb9763 bellard
                    how = SIG_BLOCK;
5398 66fb9763 bellard
                    break;
5399 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
5400 66fb9763 bellard
                    how = SIG_UNBLOCK;
5401 66fb9763 bellard
                    break;
5402 66fb9763 bellard
                case TARGET_SIG_SETMASK:
5403 66fb9763 bellard
                    how = SIG_SETMASK;
5404 66fb9763 bellard
                    break;
5405 66fb9763 bellard
                default:
5406 0da46a6e ths
                    ret = -TARGET_EINVAL;
5407 66fb9763 bellard
                    goto fail;
5408 66fb9763 bellard
                }
5409 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5410 579a97f7 bellard
                    goto efault;
5411 53a5960a pbrook
                target_to_host_old_sigset(&set, p);
5412 53a5960a pbrook
                unlock_user(p, arg2, 0);
5413 66fb9763 bellard
                set_ptr = &set;
5414 66fb9763 bellard
            } else {
5415 66fb9763 bellard
                how = 0;
5416 66fb9763 bellard
                set_ptr = NULL;
5417 66fb9763 bellard
            }
5418 a5b3b13b Richard Henderson
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5419 53a5960a pbrook
            if (!is_error(ret) && arg3) {
5420 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5421 579a97f7 bellard
                    goto efault;
5422 53a5960a pbrook
                host_to_target_old_sigset(p, &oldset);
5423 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_sigset_t));
5424 66fb9763 bellard
            }
5425 a5b3b13b Richard Henderson
#endif
5426 66fb9763 bellard
        }
5427 66fb9763 bellard
        break;
5428 e5febef5 ths
#endif
5429 66fb9763 bellard
    case TARGET_NR_rt_sigprocmask:
5430 66fb9763 bellard
        {
5431 66fb9763 bellard
            int how = arg1;
5432 66fb9763 bellard
            sigset_t set, oldset, *set_ptr;
5433 3b46e624 ths
5434 53a5960a pbrook
            if (arg2) {
5435 66fb9763 bellard
                switch(how) {
5436 66fb9763 bellard
                case TARGET_SIG_BLOCK:
5437 66fb9763 bellard
                    how = SIG_BLOCK;
5438 66fb9763 bellard
                    break;
5439 66fb9763 bellard
                case TARGET_SIG_UNBLOCK:
5440 66fb9763 bellard
                    how = SIG_UNBLOCK;
5441 66fb9763 bellard
                    break;
5442 66fb9763 bellard
                case TARGET_SIG_SETMASK:
5443 66fb9763 bellard
                    how = SIG_SETMASK;
5444 66fb9763 bellard
                    break;
5445 66fb9763 bellard
                default:
5446 0da46a6e ths
                    ret = -TARGET_EINVAL;
5447 66fb9763 bellard
                    goto fail;
5448 66fb9763 bellard
                }
5449 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
5450 579a97f7 bellard
                    goto efault;
5451 53a5960a pbrook
                target_to_host_sigset(&set, p);
5452 53a5960a pbrook
                unlock_user(p, arg2, 0);
5453 66fb9763 bellard
                set_ptr = &set;
5454 66fb9763 bellard
            } else {
5455 66fb9763 bellard
                how = 0;
5456 66fb9763 bellard
                set_ptr = NULL;
5457 66fb9763 bellard
            }
5458 66fb9763 bellard
            ret = get_errno(sigprocmask(how, set_ptr, &oldset));
5459 53a5960a pbrook
            if (!is_error(ret) && arg3) {
5460 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
5461 579a97f7 bellard
                    goto efault;
5462 53a5960a pbrook
                host_to_target_sigset(p, &oldset);
5463 c227f099 Anthony Liguori
                unlock_user(p, arg3, sizeof(target_sigset_t));
5464 66fb9763 bellard
            }
5465 66fb9763 bellard
        }
5466 66fb9763 bellard
        break;
5467 e5febef5 ths
#ifdef TARGET_NR_sigpending
5468 66fb9763 bellard
    case TARGET_NR_sigpending:
5469 66fb9763 bellard
        {
5470 66fb9763 bellard
            sigset_t set;
5471 66fb9763 bellard
            ret = get_errno(sigpending(&set));
5472 66fb9763 bellard
            if (!is_error(ret)) {
5473 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5474 579a97f7 bellard
                    goto efault;
5475 53a5960a pbrook
                host_to_target_old_sigset(p, &set);
5476 c227f099 Anthony Liguori
                unlock_user(p, arg1, sizeof(target_sigset_t));
5477 66fb9763 bellard
            }
5478 66fb9763 bellard
        }
5479 66fb9763 bellard
        break;
5480 e5febef5 ths
#endif
5481 66fb9763 bellard
    case TARGET_NR_rt_sigpending:
5482 66fb9763 bellard
        {
5483 66fb9763 bellard
            sigset_t set;
5484 66fb9763 bellard
            ret = get_errno(sigpending(&set));
5485 66fb9763 bellard
            if (!is_error(ret)) {
5486 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
5487 579a97f7 bellard
                    goto efault;
5488 53a5960a pbrook
                host_to_target_sigset(p, &set);
5489 c227f099 Anthony Liguori
                unlock_user(p, arg1, sizeof(target_sigset_t));
5490 66fb9763 bellard
            }
5491 66fb9763 bellard
        }
5492 66fb9763 bellard
        break;
5493 e5febef5 ths
#ifdef TARGET_NR_sigsuspend
5494 66fb9763 bellard
    case TARGET_NR_sigsuspend:
5495 66fb9763 bellard
        {
5496 66fb9763 bellard
            sigset_t set;
5497 f43ce12b Richard Henderson
#if defined(TARGET_ALPHA)
5498 f43ce12b Richard Henderson
            abi_ulong mask = arg1;
5499 f43ce12b Richard Henderson
            target_to_host_old_sigset(&set, &mask);
5500 f43ce12b Richard Henderson
#else
5501 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5502 579a97f7 bellard
                goto efault;
5503 53a5960a pbrook
            target_to_host_old_sigset(&set, p);
5504 53a5960a pbrook
            unlock_user(p, arg1, 0);
5505 f43ce12b Richard Henderson
#endif
5506 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
5507 66fb9763 bellard
        }
5508 66fb9763 bellard
        break;
5509 e5febef5 ths
#endif
5510 66fb9763 bellard
    case TARGET_NR_rt_sigsuspend:
5511 66fb9763 bellard
        {
5512 66fb9763 bellard
            sigset_t set;
5513 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5514 579a97f7 bellard
                goto efault;
5515 53a5960a pbrook
            target_to_host_sigset(&set, p);
5516 53a5960a pbrook
            unlock_user(p, arg1, 0);
5517 66fb9763 bellard
            ret = get_errno(sigsuspend(&set));
5518 66fb9763 bellard
        }
5519 66fb9763 bellard
        break;
5520 66fb9763 bellard
    case TARGET_NR_rt_sigtimedwait:
5521 66fb9763 bellard
        {
5522 66fb9763 bellard
            sigset_t set;
5523 66fb9763 bellard
            struct timespec uts, *puts;
5524 66fb9763 bellard
            siginfo_t uinfo;
5525 3b46e624 ths
5526 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
5527 579a97f7 bellard
                goto efault;
5528 53a5960a pbrook
            target_to_host_sigset(&set, p);
5529 53a5960a pbrook
            unlock_user(p, arg1, 0);
5530 53a5960a pbrook
            if (arg3) {
5531 66fb9763 bellard
                puts = &uts;
5532 53a5960a pbrook
                target_to_host_timespec(puts, arg3);
5533 66fb9763 bellard
            } else {
5534 66fb9763 bellard
                puts = NULL;
5535 66fb9763 bellard
            }
5536 66fb9763 bellard
            ret = get_errno(sigtimedwait(&set, &uinfo, puts));
5537 53a5960a pbrook
            if (!is_error(ret) && arg2) {
5538 c227f099 Anthony Liguori
                if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0)))
5539 579a97f7 bellard
                    goto efault;
5540 53a5960a pbrook
                host_to_target_siginfo(p, &uinfo);
5541 c227f099 Anthony Liguori
                unlock_user(p, arg2, sizeof(target_siginfo_t));
5542 66fb9763 bellard
            }
5543 66fb9763 bellard
        }
5544 66fb9763 bellard
        break;
5545 66fb9763 bellard
    case TARGET_NR_rt_sigqueueinfo:
5546 66fb9763 bellard
        {
5547 66fb9763 bellard
            siginfo_t uinfo;
5548 c227f099 Anthony Liguori
            if (!(p = lock_user(VERIFY_READ, arg3, sizeof(target_sigset_t), 1)))
5549 579a97f7 bellard
                goto efault;
5550 53a5960a pbrook
            target_to_host_siginfo(&uinfo, p);
5551 53a5960a pbrook
            unlock_user(p, arg1, 0);
5552 66fb9763 bellard
            ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
5553 66fb9763 bellard
        }
5554 66fb9763 bellard
        break;
5555 e5febef5 ths
#ifdef TARGET_NR_sigreturn
5556 66fb9763 bellard
    case TARGET_NR_sigreturn:
5557 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
5558 66fb9763 bellard
        ret = do_sigreturn(cpu_env);
5559 66fb9763 bellard
        break;
5560 e5febef5 ths
#endif
5561 66fb9763 bellard
    case TARGET_NR_rt_sigreturn:
5562 66fb9763 bellard
        /* NOTE: ret is eax, so not transcoding must be done */
5563 66fb9763 bellard
        ret = do_rt_sigreturn(cpu_env);
5564 66fb9763 bellard
        break;
5565 31e31b8a bellard
    case TARGET_NR_sethostname:
5566 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5567 579a97f7 bellard
            goto efault;
5568 53a5960a pbrook
        ret = get_errno(sethostname(p, arg2));
5569 53a5960a pbrook
        unlock_user(p, arg1, 0);
5570 31e31b8a bellard
        break;
5571 31e31b8a bellard
    case TARGET_NR_setrlimit:
5572 9de5e440 bellard
        {
5573 9de5e440 bellard
            int resource = arg1;
5574 53a5960a pbrook
            struct target_rlimit *target_rlim;
5575 9de5e440 bellard
            struct rlimit rlim;
5576 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1))
5577 579a97f7 bellard
                goto efault;
5578 81bbe906 takasi-y@ops.dti.ne.jp
            rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur);
5579 81bbe906 takasi-y@ops.dti.ne.jp
            rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max);
5580 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 0);
5581 9de5e440 bellard
            ret = get_errno(setrlimit(resource, &rlim));
5582 9de5e440 bellard
        }
5583 9de5e440 bellard
        break;
5584 31e31b8a bellard
    case TARGET_NR_getrlimit:
5585 9de5e440 bellard
        {
5586 9de5e440 bellard
            int resource = arg1;
5587 53a5960a pbrook
            struct target_rlimit *target_rlim;
5588 9de5e440 bellard
            struct rlimit rlim;
5589 3b46e624 ths
5590 9de5e440 bellard
            ret = get_errno(getrlimit(resource, &rlim));
5591 9de5e440 bellard
            if (!is_error(ret)) {
5592 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
5593 579a97f7 bellard
                    goto efault;
5594 81bbe906 takasi-y@ops.dti.ne.jp
                target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
5595 81bbe906 takasi-y@ops.dti.ne.jp
                target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
5596 53a5960a pbrook
                unlock_user_struct(target_rlim, arg2, 1);
5597 9de5e440 bellard
            }
5598 9de5e440 bellard
        }
5599 9de5e440 bellard
        break;
5600 31e31b8a bellard
    case TARGET_NR_getrusage:
5601 b409186b bellard
        {
5602 b409186b bellard
            struct rusage rusage;
5603 b409186b bellard
            ret = get_errno(getrusage(arg1, &rusage));
5604 b409186b bellard
            if (!is_error(ret)) {
5605 53a5960a pbrook
                host_to_target_rusage(arg2, &rusage);
5606 b409186b bellard
            }
5607 b409186b bellard
        }
5608 b409186b bellard
        break;
5609 31e31b8a bellard
    case TARGET_NR_gettimeofday:
5610 31e31b8a bellard
        {
5611 31e31b8a bellard
            struct timeval tv;
5612 31e31b8a bellard
            ret = get_errno(gettimeofday(&tv, NULL));
5613 31e31b8a bellard
            if (!is_error(ret)) {
5614 788f5ec4 ths
                if (copy_to_user_timeval(arg1, &tv))
5615 788f5ec4 ths
                    goto efault;
5616 31e31b8a bellard
            }
5617 31e31b8a bellard
        }
5618 31e31b8a bellard
        break;
5619 31e31b8a bellard
    case TARGET_NR_settimeofday:
5620 31e31b8a bellard
        {
5621 31e31b8a bellard
            struct timeval tv;
5622 788f5ec4 ths
            if (copy_from_user_timeval(&tv, arg1))
5623 788f5ec4 ths
                goto efault;
5624 31e31b8a bellard
            ret = get_errno(settimeofday(&tv, NULL));
5625 31e31b8a bellard
        }
5626 31e31b8a bellard
        break;
5627 a4c075f1 Ulrich Hecht
#if defined(TARGET_NR_select) && !defined(TARGET_S390X) && !defined(TARGET_S390)
5628 31e31b8a bellard
    case TARGET_NR_select:
5629 f2674e31 bellard
        {
5630 53a5960a pbrook
            struct target_sel_arg_struct *sel;
5631 992f48a0 blueswir1
            abi_ulong inp, outp, exp, tvp;
5632 53a5960a pbrook
            long nsel;
5633 53a5960a pbrook
5634 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, sel, arg1, 1))
5635 579a97f7 bellard
                goto efault;
5636 53a5960a pbrook
            nsel = tswapl(sel->n);
5637 53a5960a pbrook
            inp = tswapl(sel->inp);
5638 53a5960a pbrook
            outp = tswapl(sel->outp);
5639 53a5960a pbrook
            exp = tswapl(sel->exp);
5640 53a5960a pbrook
            tvp = tswapl(sel->tvp);
5641 53a5960a pbrook
            unlock_user_struct(sel, arg1, 0);
5642 53a5960a pbrook
            ret = do_select(nsel, inp, outp, exp, tvp);
5643 f2674e31 bellard
        }
5644 f2674e31 bellard
        break;
5645 048f6b4d bellard
#endif
5646 9e42382f Riku Voipio
#ifdef TARGET_NR_pselect6
5647 9e42382f Riku Voipio
    case TARGET_NR_pselect6:
5648 055e0906 Mike Frysinger
        {
5649 055e0906 Mike Frysinger
            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
5650 055e0906 Mike Frysinger
            fd_set rfds, wfds, efds;
5651 055e0906 Mike Frysinger
            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
5652 055e0906 Mike Frysinger
            struct timespec ts, *ts_ptr;
5653 055e0906 Mike Frysinger
5654 055e0906 Mike Frysinger
            /*
5655 055e0906 Mike Frysinger
             * The 6th arg is actually two args smashed together,
5656 055e0906 Mike Frysinger
             * so we cannot use the C library.
5657 055e0906 Mike Frysinger
             */
5658 055e0906 Mike Frysinger
            sigset_t set;
5659 055e0906 Mike Frysinger
            struct {
5660 055e0906 Mike Frysinger
                sigset_t *set;
5661 055e0906 Mike Frysinger
                size_t size;
5662 055e0906 Mike Frysinger
            } sig, *sig_ptr;
5663 055e0906 Mike Frysinger
5664 055e0906 Mike Frysinger
            abi_ulong arg_sigset, arg_sigsize, *arg7;
5665 055e0906 Mike Frysinger
            target_sigset_t *target_sigset;
5666 055e0906 Mike Frysinger
5667 055e0906 Mike Frysinger
            n = arg1;
5668 055e0906 Mike Frysinger
            rfd_addr = arg2;
5669 055e0906 Mike Frysinger
            wfd_addr = arg3;
5670 055e0906 Mike Frysinger
            efd_addr = arg4;
5671 055e0906 Mike Frysinger
            ts_addr = arg5;
5672 055e0906 Mike Frysinger
5673 055e0906 Mike Frysinger
            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
5674 055e0906 Mike Frysinger
            if (ret) {
5675 055e0906 Mike Frysinger
                goto fail;
5676 055e0906 Mike Frysinger
            }
5677 055e0906 Mike Frysinger
            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
5678 055e0906 Mike Frysinger
            if (ret) {
5679 055e0906 Mike Frysinger
                goto fail;
5680 055e0906 Mike Frysinger
            }
5681 055e0906 Mike Frysinger
            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
5682 055e0906 Mike Frysinger
            if (ret) {
5683 055e0906 Mike Frysinger
                goto fail;
5684 055e0906 Mike Frysinger
            }
5685 055e0906 Mike Frysinger
5686 055e0906 Mike Frysinger
            /*
5687 055e0906 Mike Frysinger
             * This takes a timespec, and not a timeval, so we cannot
5688 055e0906 Mike Frysinger
             * use the do_select() helper ...
5689 055e0906 Mike Frysinger
             */
5690 055e0906 Mike Frysinger
            if (ts_addr) {
5691 055e0906 Mike Frysinger
                if (target_to_host_timespec(&ts, ts_addr)) {
5692 055e0906 Mike Frysinger
                    goto efault;
5693 055e0906 Mike Frysinger
                }
5694 055e0906 Mike Frysinger
                ts_ptr = &ts;
5695 055e0906 Mike Frysinger
            } else {
5696 055e0906 Mike Frysinger
                ts_ptr = NULL;
5697 055e0906 Mike Frysinger
            }
5698 055e0906 Mike Frysinger
5699 055e0906 Mike Frysinger
            /* Extract the two packed args for the sigset */
5700 055e0906 Mike Frysinger
            if (arg6) {
5701 055e0906 Mike Frysinger
                sig_ptr = &sig;
5702 055e0906 Mike Frysinger
                sig.size = _NSIG / 8;
5703 055e0906 Mike Frysinger
5704 055e0906 Mike Frysinger
                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
5705 055e0906 Mike Frysinger
                if (!arg7) {
5706 055e0906 Mike Frysinger
                    goto efault;
5707 055e0906 Mike Frysinger
                }
5708 055e0906 Mike Frysinger
                arg_sigset = tswapl(arg7[0]);
5709 055e0906 Mike Frysinger
                arg_sigsize = tswapl(arg7[1]);
5710 055e0906 Mike Frysinger
                unlock_user(arg7, arg6, 0);
5711 055e0906 Mike Frysinger
5712 055e0906 Mike Frysinger
                if (arg_sigset) {
5713 055e0906 Mike Frysinger
                    sig.set = &set;
5714 8f04eeb3 Peter Maydell
                    if (arg_sigsize != sizeof(*target_sigset)) {
5715 8f04eeb3 Peter Maydell
                        /* Like the kernel, we enforce correct size sigsets */
5716 8f04eeb3 Peter Maydell
                        ret = -TARGET_EINVAL;
5717 8f04eeb3 Peter Maydell
                        goto fail;
5718 8f04eeb3 Peter Maydell
                    }
5719 055e0906 Mike Frysinger
                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
5720 055e0906 Mike Frysinger
                                              sizeof(*target_sigset), 1);
5721 055e0906 Mike Frysinger
                    if (!target_sigset) {
5722 055e0906 Mike Frysinger
                        goto efault;
5723 055e0906 Mike Frysinger
                    }
5724 055e0906 Mike Frysinger
                    target_to_host_sigset(&set, target_sigset);
5725 055e0906 Mike Frysinger
                    unlock_user(target_sigset, arg_sigset, 0);
5726 055e0906 Mike Frysinger
                } else {
5727 055e0906 Mike Frysinger
                    sig.set = NULL;
5728 055e0906 Mike Frysinger
                }
5729 055e0906 Mike Frysinger
            } else {
5730 055e0906 Mike Frysinger
                sig_ptr = NULL;
5731 055e0906 Mike Frysinger
            }
5732 055e0906 Mike Frysinger
5733 055e0906 Mike Frysinger
            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
5734 055e0906 Mike Frysinger
                                         ts_ptr, sig_ptr));
5735 055e0906 Mike Frysinger
5736 055e0906 Mike Frysinger
            if (!is_error(ret)) {
5737 055e0906 Mike Frysinger
                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
5738 055e0906 Mike Frysinger
                    goto efault;
5739 055e0906 Mike Frysinger
                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
5740 055e0906 Mike Frysinger
                    goto efault;
5741 055e0906 Mike Frysinger
                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
5742 055e0906 Mike Frysinger
                    goto efault;
5743 055e0906 Mike Frysinger
5744 055e0906 Mike Frysinger
                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
5745 055e0906 Mike Frysinger
                    goto efault;
5746 055e0906 Mike Frysinger
            }
5747 055e0906 Mike Frysinger
        }
5748 055e0906 Mike Frysinger
        break;
5749 9e42382f Riku Voipio
#endif
5750 31e31b8a bellard
    case TARGET_NR_symlink:
5751 53a5960a pbrook
        {
5752 53a5960a pbrook
            void *p2;
5753 53a5960a pbrook
            p = lock_user_string(arg1);
5754 53a5960a pbrook
            p2 = lock_user_string(arg2);
5755 579a97f7 bellard
            if (!p || !p2)
5756 579a97f7 bellard
                ret = -TARGET_EFAULT;
5757 579a97f7 bellard
            else
5758 579a97f7 bellard
                ret = get_errno(symlink(p, p2));
5759 53a5960a pbrook
            unlock_user(p2, arg2, 0);
5760 53a5960a pbrook
            unlock_user(p, arg1, 0);
5761 53a5960a pbrook
        }
5762 31e31b8a bellard
        break;
5763 f0b6243d ths
#if defined(TARGET_NR_symlinkat) && defined(__NR_symlinkat)
5764 f0b6243d ths
    case TARGET_NR_symlinkat:
5765 f0b6243d ths
        {
5766 579a97f7 bellard
            void *p2;
5767 f0b6243d ths
            p  = lock_user_string(arg1);
5768 f0b6243d ths
            p2 = lock_user_string(arg3);
5769 579a97f7 bellard
            if (!p || !p2)
5770 0da46a6e ths
                ret = -TARGET_EFAULT;
5771 f0b6243d ths
            else
5772 f0b6243d ths
                ret = get_errno(sys_symlinkat(p, arg2, p2));
5773 579a97f7 bellard
            unlock_user(p2, arg3, 0);
5774 579a97f7 bellard
            unlock_user(p, arg1, 0);
5775 f0b6243d ths
        }
5776 f0b6243d ths
        break;
5777 f0b6243d ths
#endif
5778 ebc05488 bellard
#ifdef TARGET_NR_oldlstat
5779 31e31b8a bellard
    case TARGET_NR_oldlstat:
5780 31e31b8a bellard
        goto unimplemented;
5781 ebc05488 bellard
#endif
5782 31e31b8a bellard
    case TARGET_NR_readlink:
5783 53a5960a pbrook
        {
5784 d088d664 aurel32
            void *p2, *temp;
5785 53a5960a pbrook
            p = lock_user_string(arg1);
5786 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
5787 579a97f7 bellard
            if (!p || !p2)
5788 579a97f7 bellard
                ret = -TARGET_EFAULT;
5789 d088d664 aurel32
            else {
5790 d088d664 aurel32
                if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
5791 d088d664 aurel32
                    char real[PATH_MAX];
5792 d088d664 aurel32
                    temp = realpath(exec_path,real);
5793 d088d664 aurel32
                    ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
5794 d088d664 aurel32
                    snprintf((char *)p2, arg3, "%s", real);
5795 d088d664 aurel32
                    }
5796 d088d664 aurel32
                else
5797 d088d664 aurel32
                    ret = get_errno(readlink(path(p), p2, arg3));
5798 d088d664 aurel32
            }
5799 53a5960a pbrook
            unlock_user(p2, arg2, ret);
5800 53a5960a pbrook
            unlock_user(p, arg1, 0);
5801 53a5960a pbrook
        }
5802 31e31b8a bellard
        break;
5803 5e0ccb18 ths
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
5804 5e0ccb18 ths
    case TARGET_NR_readlinkat:
5805 5e0ccb18 ths
        {
5806 579a97f7 bellard
            void *p2;
5807 5e0ccb18 ths
            p  = lock_user_string(arg2);
5808 579a97f7 bellard
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
5809 579a97f7 bellard
            if (!p || !p2)
5810 0da46a6e ths
                ret = -TARGET_EFAULT;
5811 5e0ccb18 ths
            else
5812 5e0ccb18 ths
                ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
5813 579a97f7 bellard
            unlock_user(p2, arg3, ret);
5814 579a97f7 bellard
            unlock_user(p, arg2, 0);
5815 5e0ccb18 ths
        }
5816 5e0ccb18 ths
        break;
5817 5e0ccb18 ths
#endif
5818 e5febef5 ths
#ifdef TARGET_NR_uselib
5819 31e31b8a bellard
    case TARGET_NR_uselib:
5820 31e31b8a bellard
        goto unimplemented;
5821 e5febef5 ths
#endif
5822 e5febef5 ths
#ifdef TARGET_NR_swapon
5823 31e31b8a bellard
    case TARGET_NR_swapon:
5824 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5825 579a97f7 bellard
            goto efault;
5826 53a5960a pbrook
        ret = get_errno(swapon(p, arg2));
5827 53a5960a pbrook
        unlock_user(p, arg1, 0);
5828 31e31b8a bellard
        break;
5829 e5febef5 ths
#endif
5830 31e31b8a bellard
    case TARGET_NR_reboot:
5831 31e31b8a bellard
        goto unimplemented;
5832 e5febef5 ths
#ifdef TARGET_NR_readdir
5833 31e31b8a bellard
    case TARGET_NR_readdir:
5834 31e31b8a bellard
        goto unimplemented;
5835 e5febef5 ths
#endif
5836 e5febef5 ths
#ifdef TARGET_NR_mmap
5837 31e31b8a bellard
    case TARGET_NR_mmap:
5838 a4c075f1 Ulrich Hecht
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || \
5839 a4c075f1 Ulrich Hecht
    defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE) \
5840 a4c075f1 Ulrich Hecht
    || defined(TARGET_S390X)
5841 31e31b8a bellard
        {
5842 992f48a0 blueswir1
            abi_ulong *v;
5843 992f48a0 blueswir1
            abi_ulong v1, v2, v3, v4, v5, v6;
5844 579a97f7 bellard
            if (!(v = lock_user(VERIFY_READ, arg1, 6 * sizeof(abi_ulong), 1)))
5845 579a97f7 bellard
                goto efault;
5846 53a5960a pbrook
            v1 = tswapl(v[0]);
5847 53a5960a pbrook
            v2 = tswapl(v[1]);
5848 53a5960a pbrook
            v3 = tswapl(v[2]);
5849 53a5960a pbrook
            v4 = tswapl(v[3]);
5850 53a5960a pbrook
            v5 = tswapl(v[4]);
5851 53a5960a pbrook
            v6 = tswapl(v[5]);
5852 53a5960a pbrook
            unlock_user(v, arg1, 0);
5853 5fafdf24 ths
            ret = get_errno(target_mmap(v1, v2, v3,
5854 5286db75 bellard
                                        target_to_host_bitmask(v4, mmap_flags_tbl),
5855 5286db75 bellard
                                        v5, v6));
5856 31e31b8a bellard
        }
5857 31e31b8a bellard
#else
5858 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5859 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5860 6fb883e8 bellard
                                    arg5,
5861 6fb883e8 bellard
                                    arg6));
5862 31e31b8a bellard
#endif
5863 6fb883e8 bellard
        break;
5864 e5febef5 ths
#endif
5865 a315a145 bellard
#ifdef TARGET_NR_mmap2
5866 6fb883e8 bellard
    case TARGET_NR_mmap2:
5867 bb7ec043 pbrook
#ifndef MMAP_SHIFT
5868 c573ff67 bellard
#define MMAP_SHIFT 12
5869 c573ff67 bellard
#endif
5870 5fafdf24 ths
        ret = get_errno(target_mmap(arg1, arg2, arg3,
5871 5fafdf24 ths
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
5872 5286db75 bellard
                                    arg5,
5873 c573ff67 bellard
                                    arg6 << MMAP_SHIFT));
5874 31e31b8a bellard
        break;
5875 a315a145 bellard
#endif
5876 31e31b8a bellard
    case TARGET_NR_munmap:
5877 54936004 bellard
        ret = get_errno(target_munmap(arg1, arg2));
5878 31e31b8a bellard
        break;
5879 9de5e440 bellard
    case TARGET_NR_mprotect:
5880 97374d38 Paul Brook
        {
5881 97374d38 Paul Brook
            TaskState *ts = ((CPUState *)cpu_env)->opaque;
5882 97374d38 Paul Brook
            /* Special hack to detect libc making the stack executable.  */
5883 97374d38 Paul Brook
            if ((arg3 & PROT_GROWSDOWN)
5884 97374d38 Paul Brook
                && arg1 >= ts->info->stack_limit
5885 97374d38 Paul Brook
                && arg1 <= ts->info->start_stack) {
5886 97374d38 Paul Brook
                arg3 &= ~PROT_GROWSDOWN;
5887 97374d38 Paul Brook
                arg2 = arg2 + arg1 - ts->info->stack_limit;
5888 97374d38 Paul Brook
                arg1 = ts->info->stack_limit;
5889 97374d38 Paul Brook
            }
5890 97374d38 Paul Brook
        }
5891 54936004 bellard
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
5892 9de5e440 bellard
        break;
5893 e5febef5 ths
#ifdef TARGET_NR_mremap
5894 9de5e440 bellard
    case TARGET_NR_mremap:
5895 54936004 bellard
        ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
5896 9de5e440 bellard
        break;
5897 e5febef5 ths
#endif
5898 53a5960a pbrook
        /* ??? msync/mlock/munlock are broken for softmmu.  */
5899 e5febef5 ths
#ifdef TARGET_NR_msync
5900 9de5e440 bellard
    case TARGET_NR_msync:
5901 53a5960a pbrook
        ret = get_errno(msync(g2h(arg1), arg2, arg3));
5902 9de5e440 bellard
        break;
5903 e5febef5 ths
#endif
5904 e5febef5 ths
#ifdef TARGET_NR_mlock
5905 9de5e440 bellard
    case TARGET_NR_mlock:
5906 53a5960a pbrook
        ret = get_errno(mlock(g2h(arg1), arg2));
5907 9de5e440 bellard
        break;
5908 e5febef5 ths
#endif
5909 e5febef5 ths
#ifdef TARGET_NR_munlock
5910 9de5e440 bellard
    case TARGET_NR_munlock:
5911 53a5960a pbrook
        ret = get_errno(munlock(g2h(arg1), arg2));
5912 9de5e440 bellard
        break;
5913 e5febef5 ths
#endif
5914 e5febef5 ths
#ifdef TARGET_NR_mlockall
5915 9de5e440 bellard
    case TARGET_NR_mlockall:
5916 9de5e440 bellard
        ret = get_errno(mlockall(arg1));
5917 9de5e440 bellard
        break;
5918 e5febef5 ths
#endif
5919 e5febef5 ths
#ifdef TARGET_NR_munlockall
5920 9de5e440 bellard
    case TARGET_NR_munlockall:
5921 9de5e440 bellard
        ret = get_errno(munlockall());
5922 9de5e440 bellard
        break;
5923 e5febef5 ths
#endif
5924 31e31b8a bellard
    case TARGET_NR_truncate:
5925 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5926 579a97f7 bellard
            goto efault;
5927 53a5960a pbrook
        ret = get_errno(truncate(p, arg2));
5928 53a5960a pbrook
        unlock_user(p, arg1, 0);
5929 31e31b8a bellard
        break;
5930 31e31b8a bellard
    case TARGET_NR_ftruncate:
5931 31e31b8a bellard
        ret = get_errno(ftruncate(arg1, arg2));
5932 31e31b8a bellard
        break;
5933 31e31b8a bellard
    case TARGET_NR_fchmod:
5934 31e31b8a bellard
        ret = get_errno(fchmod(arg1, arg2));
5935 31e31b8a bellard
        break;
5936 814d7977 ths
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
5937 814d7977 ths
    case TARGET_NR_fchmodat:
5938 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
5939 579a97f7 bellard
            goto efault;
5940 465c9f06 aurel32
        ret = get_errno(sys_fchmodat(arg1, p, arg3));
5941 579a97f7 bellard
        unlock_user(p, arg2, 0);
5942 814d7977 ths
        break;
5943 814d7977 ths
#endif
5944 31e31b8a bellard
    case TARGET_NR_getpriority:
5945 c6cda17a ths
        /* libc does special remapping of the return value of
5946 c6cda17a ths
         * sys_getpriority() so it's just easiest to call
5947 c6cda17a ths
         * sys_getpriority() directly rather than through libc. */
5948 69137206 Ulrich Hecht
        ret = get_errno(sys_getpriority(arg1, arg2));
5949 31e31b8a bellard
        break;
5950 31e31b8a bellard
    case TARGET_NR_setpriority:
5951 31e31b8a bellard
        ret = get_errno(setpriority(arg1, arg2, arg3));
5952 31e31b8a bellard
        break;
5953 ebc05488 bellard
#ifdef TARGET_NR_profil
5954 31e31b8a bellard
    case TARGET_NR_profil:
5955 31e31b8a bellard
        goto unimplemented;
5956 ebc05488 bellard
#endif
5957 31e31b8a bellard
    case TARGET_NR_statfs:
5958 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5959 579a97f7 bellard
            goto efault;
5960 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
5961 53a5960a pbrook
        unlock_user(p, arg1, 0);
5962 31e31b8a bellard
    convert_statfs:
5963 31e31b8a bellard
        if (!is_error(ret)) {
5964 53a5960a pbrook
            struct target_statfs *target_stfs;
5965 3b46e624 ths
5966 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg2, 0))
5967 579a97f7 bellard
                goto efault;
5968 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
5969 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5970 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5971 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
5972 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
5973 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
5974 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
5975 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
5976 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
5977 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
5978 53a5960a pbrook
            unlock_user_struct(target_stfs, arg2, 1);
5979 31e31b8a bellard
        }
5980 31e31b8a bellard
        break;
5981 31e31b8a bellard
    case TARGET_NR_fstatfs:
5982 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
5983 31e31b8a bellard
        goto convert_statfs;
5984 56c8f68f bellard
#ifdef TARGET_NR_statfs64
5985 56c8f68f bellard
    case TARGET_NR_statfs64:
5986 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
5987 579a97f7 bellard
            goto efault;
5988 53a5960a pbrook
        ret = get_errno(statfs(path(p), &stfs));
5989 53a5960a pbrook
        unlock_user(p, arg1, 0);
5990 56c8f68f bellard
    convert_statfs64:
5991 56c8f68f bellard
        if (!is_error(ret)) {
5992 53a5960a pbrook
            struct target_statfs64 *target_stfs;
5993 3b46e624 ths
5994 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_stfs, arg3, 0))
5995 579a97f7 bellard
                goto efault;
5996 579a97f7 bellard
            __put_user(stfs.f_type, &target_stfs->f_type);
5997 579a97f7 bellard
            __put_user(stfs.f_bsize, &target_stfs->f_bsize);
5998 579a97f7 bellard
            __put_user(stfs.f_blocks, &target_stfs->f_blocks);
5999 579a97f7 bellard
            __put_user(stfs.f_bfree, &target_stfs->f_bfree);
6000 579a97f7 bellard
            __put_user(stfs.f_bavail, &target_stfs->f_bavail);
6001 579a97f7 bellard
            __put_user(stfs.f_files, &target_stfs->f_files);
6002 579a97f7 bellard
            __put_user(stfs.f_ffree, &target_stfs->f_ffree);
6003 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid.val[0]);
6004 579a97f7 bellard
            __put_user(stfs.f_fsid.__val[1], &target_stfs->f_fsid.val[1]);
6005 579a97f7 bellard
            __put_user(stfs.f_namelen, &target_stfs->f_namelen);
6006 579a97f7 bellard
            unlock_user_struct(target_stfs, arg3, 1);
6007 56c8f68f bellard
        }
6008 56c8f68f bellard
        break;
6009 56c8f68f bellard
    case TARGET_NR_fstatfs64:
6010 56c8f68f bellard
        ret = get_errno(fstatfs(arg1, &stfs));
6011 56c8f68f bellard
        goto convert_statfs64;
6012 56c8f68f bellard
#endif
6013 ebc05488 bellard
#ifdef TARGET_NR_ioperm
6014 31e31b8a bellard
    case TARGET_NR_ioperm:
6015 31e31b8a bellard
        goto unimplemented;
6016 ebc05488 bellard
#endif
6017 e5febef5 ths
#ifdef TARGET_NR_socketcall
6018 31e31b8a bellard
    case TARGET_NR_socketcall:
6019 53a5960a pbrook
        ret = do_socketcall(arg1, arg2);
6020 31e31b8a bellard
        break;
6021 e5febef5 ths
#endif
6022 3532fa74 bellard
#ifdef TARGET_NR_accept
6023 3532fa74 bellard
    case TARGET_NR_accept:
6024 1be9e1dc pbrook
        ret = do_accept(arg1, arg2, arg3);
6025 3532fa74 bellard
        break;
6026 3532fa74 bellard
#endif
6027 3532fa74 bellard
#ifdef TARGET_NR_bind
6028 3532fa74 bellard
    case TARGET_NR_bind:
6029 3532fa74 bellard
        ret = do_bind(arg1, arg2, arg3);
6030 3532fa74 bellard
        break;
6031 3532fa74 bellard
#endif
6032 3532fa74 bellard
#ifdef TARGET_NR_connect
6033 3532fa74 bellard
    case TARGET_NR_connect:
6034 3532fa74 bellard
        ret = do_connect(arg1, arg2, arg3);
6035 3532fa74 bellard
        break;
6036 3532fa74 bellard
#endif
6037 3532fa74 bellard
#ifdef TARGET_NR_getpeername
6038 3532fa74 bellard
    case TARGET_NR_getpeername:
6039 1be9e1dc pbrook
        ret = do_getpeername(arg1, arg2, arg3);
6040 3532fa74 bellard
        break;
6041 3532fa74 bellard
#endif
6042 3532fa74 bellard
#ifdef TARGET_NR_getsockname
6043 3532fa74 bellard
    case TARGET_NR_getsockname:
6044 1be9e1dc pbrook
        ret = do_getsockname(arg1, arg2, arg3);
6045 3532fa74 bellard
        break;
6046 3532fa74 bellard
#endif
6047 3532fa74 bellard
#ifdef TARGET_NR_getsockopt
6048 3532fa74 bellard
    case TARGET_NR_getsockopt:
6049 3532fa74 bellard
        ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5);
6050 3532fa74 bellard
        break;
6051 3532fa74 bellard
#endif
6052 3532fa74 bellard
#ifdef TARGET_NR_listen
6053 3532fa74 bellard
    case TARGET_NR_listen:
6054 1be9e1dc pbrook
        ret = get_errno(listen(arg1, arg2));
6055 3532fa74 bellard
        break;
6056 3532fa74 bellard
#endif
6057 3532fa74 bellard
#ifdef TARGET_NR_recv
6058 3532fa74 bellard
    case TARGET_NR_recv:
6059 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, 0, 0);
6060 3532fa74 bellard
        break;
6061 3532fa74 bellard
#endif
6062 3532fa74 bellard
#ifdef TARGET_NR_recvfrom
6063 3532fa74 bellard
    case TARGET_NR_recvfrom:
6064 214201bd pbrook
        ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6);
6065 3532fa74 bellard
        break;
6066 3532fa74 bellard
#endif
6067 3532fa74 bellard
#ifdef TARGET_NR_recvmsg
6068 3532fa74 bellard
    case TARGET_NR_recvmsg:
6069 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 0);
6070 3532fa74 bellard
        break;
6071 3532fa74 bellard
#endif
6072 3532fa74 bellard
#ifdef TARGET_NR_send
6073 3532fa74 bellard
    case TARGET_NR_send:
6074 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, 0, 0);
6075 3532fa74 bellard
        break;
6076 3532fa74 bellard
#endif
6077 3532fa74 bellard
#ifdef TARGET_NR_sendmsg
6078 3532fa74 bellard
    case TARGET_NR_sendmsg:
6079 3532fa74 bellard
        ret = do_sendrecvmsg(arg1, arg2, arg3, 1);
6080 3532fa74 bellard
        break;
6081 3532fa74 bellard
#endif
6082 3532fa74 bellard
#ifdef TARGET_NR_sendto
6083 3532fa74 bellard
    case TARGET_NR_sendto:
6084 1be9e1dc pbrook
        ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6);
6085 3532fa74 bellard
        break;
6086 3532fa74 bellard
#endif
6087 3532fa74 bellard
#ifdef TARGET_NR_shutdown
6088 3532fa74 bellard
    case TARGET_NR_shutdown:
6089 1be9e1dc pbrook
        ret = get_errno(shutdown(arg1, arg2));
6090 3532fa74 bellard
        break;
6091 3532fa74 bellard
#endif
6092 3532fa74 bellard
#ifdef TARGET_NR_socket
6093 3532fa74 bellard
    case TARGET_NR_socket:
6094 3532fa74 bellard
        ret = do_socket(arg1, arg2, arg3);
6095 3532fa74 bellard
        break;
6096 3532fa74 bellard
#endif
6097 3532fa74 bellard
#ifdef TARGET_NR_socketpair
6098 3532fa74 bellard
    case TARGET_NR_socketpair:
6099 1be9e1dc pbrook
        ret = do_socketpair(arg1, arg2, arg3, arg4);
6100 3532fa74 bellard
        break;
6101 3532fa74 bellard
#endif
6102 3532fa74 bellard
#ifdef TARGET_NR_setsockopt
6103 3532fa74 bellard
    case TARGET_NR_setsockopt:
6104 3532fa74 bellard
        ret = do_setsockopt(arg1, arg2, arg3, arg4, (socklen_t) arg5);
6105 3532fa74 bellard
        break;
6106 3532fa74 bellard
#endif
6107 7494b0f9 ths
6108 31e31b8a bellard
    case TARGET_NR_syslog:
6109 579a97f7 bellard
        if (!(p = lock_user_string(arg2)))
6110 579a97f7 bellard
            goto efault;
6111 e5574487 ths
        ret = get_errno(sys_syslog((int)arg1, p, (int)arg3));
6112 e5574487 ths
        unlock_user(p, arg2, 0);
6113 7494b0f9 ths
        break;
6114 7494b0f9 ths
6115 31e31b8a bellard
    case TARGET_NR_setitimer:
6116 66fb9763 bellard
        {
6117 66fb9763 bellard
            struct itimerval value, ovalue, *pvalue;
6118 66fb9763 bellard
6119 53a5960a pbrook
            if (arg2) {
6120 66fb9763 bellard
                pvalue = &value;
6121 788f5ec4 ths
                if (copy_from_user_timeval(&pvalue->it_interval, arg2)
6122 788f5ec4 ths
                    || copy_from_user_timeval(&pvalue->it_value,
6123 788f5ec4 ths
                                              arg2 + sizeof(struct target_timeval)))
6124 788f5ec4 ths
                    goto efault;
6125 66fb9763 bellard
            } else {
6126 66fb9763 bellard
                pvalue = NULL;
6127 66fb9763 bellard
            }
6128 66fb9763 bellard
            ret = get_errno(setitimer(arg1, pvalue, &ovalue));
6129 53a5960a pbrook
            if (!is_error(ret) && arg3) {
6130 788f5ec4 ths
                if (copy_to_user_timeval(arg3,
6131 788f5ec4 ths
                                         &ovalue.it_interval)
6132 788f5ec4 ths
                    || copy_to_user_timeval(arg3 + sizeof(struct target_timeval),
6133 788f5ec4 ths
                                            &ovalue.it_value))
6134 788f5ec4 ths
                    goto efault;
6135 66fb9763 bellard
            }
6136 66fb9763 bellard
        }
6137 66fb9763 bellard
        break;
6138 31e31b8a bellard
    case TARGET_NR_getitimer:
6139 66fb9763 bellard
        {
6140 66fb9763 bellard
            struct itimerval value;
6141 3b46e624 ths
6142 66fb9763 bellard
            ret = get_errno(getitimer(arg1, &value));
6143 53a5960a pbrook
            if (!is_error(ret) && arg2) {
6144 788f5ec4 ths
                if (copy_to_user_timeval(arg2,
6145 788f5ec4 ths
                                         &value.it_interval)
6146 788f5ec4 ths
                    || copy_to_user_timeval(arg2 + sizeof(struct target_timeval),
6147 788f5ec4 ths
                                            &value.it_value))
6148 788f5ec4 ths
                    goto efault;
6149 66fb9763 bellard
            }
6150 66fb9763 bellard
        }
6151 66fb9763 bellard
        break;
6152 31e31b8a bellard
    case TARGET_NR_stat:
6153 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6154 579a97f7 bellard
            goto efault;
6155 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
6156 53a5960a pbrook
        unlock_user(p, arg1, 0);
6157 31e31b8a bellard
        goto do_stat;
6158 31e31b8a bellard
    case TARGET_NR_lstat:
6159 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6160 579a97f7 bellard
            goto efault;
6161 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
6162 53a5960a pbrook
        unlock_user(p, arg1, 0);
6163 31e31b8a bellard
        goto do_stat;
6164 31e31b8a bellard
    case TARGET_NR_fstat:
6165 31e31b8a bellard
        {
6166 31e31b8a bellard
            ret = get_errno(fstat(arg1, &st));
6167 31e31b8a bellard
        do_stat:
6168 31e31b8a bellard
            if (!is_error(ret)) {
6169 53a5960a pbrook
                struct target_stat *target_st;
6170 e3584658 ths
6171 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
6172 579a97f7 bellard
                    goto efault;
6173 12727917 Ulrich Hecht
                memset(target_st, 0, sizeof(*target_st));
6174 d2fd1af7 bellard
                __put_user(st.st_dev, &target_st->st_dev);
6175 d2fd1af7 bellard
                __put_user(st.st_ino, &target_st->st_ino);
6176 d2fd1af7 bellard
                __put_user(st.st_mode, &target_st->st_mode);
6177 d2fd1af7 bellard
                __put_user(st.st_uid, &target_st->st_uid);
6178 d2fd1af7 bellard
                __put_user(st.st_gid, &target_st->st_gid);
6179 d2fd1af7 bellard
                __put_user(st.st_nlink, &target_st->st_nlink);
6180 d2fd1af7 bellard
                __put_user(st.st_rdev, &target_st->st_rdev);
6181 d2fd1af7 bellard
                __put_user(st.st_size, &target_st->st_size);
6182 d2fd1af7 bellard
                __put_user(st.st_blksize, &target_st->st_blksize);
6183 d2fd1af7 bellard
                __put_user(st.st_blocks, &target_st->st_blocks);
6184 d2fd1af7 bellard
                __put_user(st.st_atime, &target_st->target_st_atime);
6185 d2fd1af7 bellard
                __put_user(st.st_mtime, &target_st->target_st_mtime);
6186 d2fd1af7 bellard
                __put_user(st.st_ctime, &target_st->target_st_ctime);
6187 53a5960a pbrook
                unlock_user_struct(target_st, arg2, 1);
6188 31e31b8a bellard
            }
6189 31e31b8a bellard
        }
6190 31e31b8a bellard
        break;
6191 ebc05488 bellard
#ifdef TARGET_NR_olduname
6192 31e31b8a bellard
    case TARGET_NR_olduname:
6193 31e31b8a bellard
        goto unimplemented;
6194 ebc05488 bellard
#endif
6195 ebc05488 bellard
#ifdef TARGET_NR_iopl
6196 31e31b8a bellard
    case TARGET_NR_iopl:
6197 31e31b8a bellard
        goto unimplemented;
6198 ebc05488 bellard
#endif
6199 31e31b8a bellard
    case TARGET_NR_vhangup:
6200 31e31b8a bellard
        ret = get_errno(vhangup());
6201 31e31b8a bellard
        break;
6202 ebc05488 bellard
#ifdef TARGET_NR_idle
6203 31e31b8a bellard
    case TARGET_NR_idle:
6204 31e31b8a bellard
        goto unimplemented;
6205 ebc05488 bellard
#endif
6206 42ad6ae9 bellard
#ifdef TARGET_NR_syscall
6207 42ad6ae9 bellard
    case TARGET_NR_syscall:
6208 5945cfcb Peter Maydell
        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
6209 5945cfcb Peter Maydell
                         arg6, arg7, arg8, 0);
6210 5945cfcb Peter Maydell
        break;
6211 42ad6ae9 bellard
#endif
6212 31e31b8a bellard
    case TARGET_NR_wait4:
6213 31e31b8a bellard
        {
6214 31e31b8a bellard
            int status;
6215 992f48a0 blueswir1
            abi_long status_ptr = arg2;
6216 31e31b8a bellard
            struct rusage rusage, *rusage_ptr;
6217 992f48a0 blueswir1
            abi_ulong target_rusage = arg4;
6218 31e31b8a bellard
            if (target_rusage)
6219 31e31b8a bellard
                rusage_ptr = &rusage;
6220 31e31b8a bellard
            else
6221 31e31b8a bellard
                rusage_ptr = NULL;
6222 31e31b8a bellard
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
6223 31e31b8a bellard
            if (!is_error(ret)) {
6224 2f619698 bellard
                if (status_ptr) {
6225 1d9d8b55 pbrook
                    status = host_to_target_waitstatus(status);
6226 2f619698 bellard
                    if (put_user_s32(status, status_ptr))
6227 2f619698 bellard
                        goto efault;
6228 31e31b8a bellard
                }
6229 2f619698 bellard
                if (target_rusage)
6230 2f619698 bellard
                    host_to_target_rusage(target_rusage, &rusage);
6231 31e31b8a bellard
            }
6232 31e31b8a bellard
        }
6233 31e31b8a bellard
        break;
6234 e5febef5 ths
#ifdef TARGET_NR_swapoff
6235 31e31b8a bellard
    case TARGET_NR_swapoff:
6236 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6237 579a97f7 bellard
            goto efault;
6238 53a5960a pbrook
        ret = get_errno(swapoff(p));
6239 53a5960a pbrook
        unlock_user(p, arg1, 0);
6240 31e31b8a bellard
        break;
6241 e5febef5 ths
#endif
6242 31e31b8a bellard
    case TARGET_NR_sysinfo:
6243 a5448a7d bellard
        {
6244 53a5960a pbrook
            struct target_sysinfo *target_value;
6245 a5448a7d bellard
            struct sysinfo value;
6246 a5448a7d bellard
            ret = get_errno(sysinfo(&value));
6247 53a5960a pbrook
            if (!is_error(ret) && arg1)
6248 a5448a7d bellard
            {
6249 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_value, arg1, 0))
6250 579a97f7 bellard
                    goto efault;
6251 a5448a7d bellard
                __put_user(value.uptime, &target_value->uptime);
6252 a5448a7d bellard
                __put_user(value.loads[0], &target_value->loads[0]);
6253 a5448a7d bellard
                __put_user(value.loads[1], &target_value->loads[1]);
6254 a5448a7d bellard
                __put_user(value.loads[2], &target_value->loads[2]);
6255 a5448a7d bellard
                __put_user(value.totalram, &target_value->totalram);
6256 a5448a7d bellard
                __put_user(value.freeram, &target_value->freeram);
6257 a5448a7d bellard
                __put_user(value.sharedram, &target_value->sharedram);
6258 a5448a7d bellard
                __put_user(value.bufferram, &target_value->bufferram);
6259 a5448a7d bellard
                __put_user(value.totalswap, &target_value->totalswap);
6260 a5448a7d bellard
                __put_user(value.freeswap, &target_value->freeswap);
6261 a5448a7d bellard
                __put_user(value.procs, &target_value->procs);
6262 a5448a7d bellard
                __put_user(value.totalhigh, &target_value->totalhigh);
6263 a5448a7d bellard
                __put_user(value.freehigh, &target_value->freehigh);
6264 a5448a7d bellard
                __put_user(value.mem_unit, &target_value->mem_unit);
6265 53a5960a pbrook
                unlock_user_struct(target_value, arg1, 1);
6266 a5448a7d bellard
            }
6267 a5448a7d bellard
        }
6268 a5448a7d bellard
        break;
6269 e5febef5 ths
#ifdef TARGET_NR_ipc
6270 31e31b8a bellard
    case TARGET_NR_ipc:
6271 8853f86e bellard
        ret = do_ipc(arg1, arg2, arg3, arg4, arg5, arg6);
6272 8853f86e bellard
        break;
6273 e5febef5 ths
#endif
6274 e5289087 aurel32
#ifdef TARGET_NR_semget
6275 e5289087 aurel32
    case TARGET_NR_semget:
6276 e5289087 aurel32
        ret = get_errno(semget(arg1, arg2, arg3));
6277 e5289087 aurel32
        break;
6278 e5289087 aurel32
#endif
6279 e5289087 aurel32
#ifdef TARGET_NR_semop
6280 e5289087 aurel32
    case TARGET_NR_semop:
6281 e5289087 aurel32
        ret = get_errno(do_semop(arg1, arg2, arg3));
6282 e5289087 aurel32
        break;
6283 e5289087 aurel32
#endif
6284 e5289087 aurel32
#ifdef TARGET_NR_semctl
6285 e5289087 aurel32
    case TARGET_NR_semctl:
6286 e5289087 aurel32
        ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
6287 e5289087 aurel32
        break;
6288 e5289087 aurel32
#endif
6289 eeb438c1 aurel32
#ifdef TARGET_NR_msgctl
6290 eeb438c1 aurel32
    case TARGET_NR_msgctl:
6291 eeb438c1 aurel32
        ret = do_msgctl(arg1, arg2, arg3);
6292 eeb438c1 aurel32
        break;
6293 eeb438c1 aurel32
#endif
6294 eeb438c1 aurel32
#ifdef TARGET_NR_msgget
6295 eeb438c1 aurel32
    case TARGET_NR_msgget:
6296 eeb438c1 aurel32
        ret = get_errno(msgget(arg1, arg2));
6297 eeb438c1 aurel32
        break;
6298 eeb438c1 aurel32
#endif
6299 eeb438c1 aurel32
#ifdef TARGET_NR_msgrcv
6300 eeb438c1 aurel32
    case TARGET_NR_msgrcv:
6301 eeb438c1 aurel32
        ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5);
6302 eeb438c1 aurel32
        break;
6303 eeb438c1 aurel32
#endif
6304 eeb438c1 aurel32
#ifdef TARGET_NR_msgsnd
6305 eeb438c1 aurel32
    case TARGET_NR_msgsnd:
6306 eeb438c1 aurel32
        ret = do_msgsnd(arg1, arg2, arg3, arg4);
6307 eeb438c1 aurel32
        break;
6308 eeb438c1 aurel32
#endif
6309 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmget
6310 88a8c984 Riku Voipio
    case TARGET_NR_shmget:
6311 88a8c984 Riku Voipio
        ret = get_errno(shmget(arg1, arg2, arg3));
6312 88a8c984 Riku Voipio
        break;
6313 88a8c984 Riku Voipio
#endif
6314 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmctl
6315 88a8c984 Riku Voipio
    case TARGET_NR_shmctl:
6316 88a8c984 Riku Voipio
        ret = do_shmctl(arg1, arg2, arg3);
6317 88a8c984 Riku Voipio
        break;
6318 88a8c984 Riku Voipio
#endif
6319 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmat
6320 88a8c984 Riku Voipio
    case TARGET_NR_shmat:
6321 88a8c984 Riku Voipio
        ret = do_shmat(arg1, arg2, arg3);
6322 88a8c984 Riku Voipio
        break;
6323 88a8c984 Riku Voipio
#endif
6324 88a8c984 Riku Voipio
#ifdef TARGET_NR_shmdt
6325 88a8c984 Riku Voipio
    case TARGET_NR_shmdt:
6326 88a8c984 Riku Voipio
        ret = do_shmdt(arg1);
6327 88a8c984 Riku Voipio
        break;
6328 88a8c984 Riku Voipio
#endif
6329 31e31b8a bellard
    case TARGET_NR_fsync:
6330 31e31b8a bellard
        ret = get_errno(fsync(arg1));
6331 31e31b8a bellard
        break;
6332 31e31b8a bellard
    case TARGET_NR_clone:
6333 a4b388ff Richard Henderson
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
6334 0b6d3ae0 aurel32
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
6335 b15ad61c edgar_igl
#elif defined(TARGET_CRIS)
6336 b15ad61c edgar_igl
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
6337 a4c075f1 Ulrich Hecht
#elif defined(TARGET_S390X)
6338 a4c075f1 Ulrich Hecht
        ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
6339 0b6d3ae0 aurel32
#else
6340 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
6341 0b6d3ae0 aurel32
#endif
6342 1b6b029e bellard
        break;
6343 ec86b0fb bellard
#ifdef __NR_exit_group
6344 ec86b0fb bellard
        /* new thread calls */
6345 ec86b0fb bellard
    case TARGET_NR_exit_group:
6346 9788c9ca Juan Quintela
#ifdef TARGET_GPROF
6347 6d946cda aurel32
        _mcleanup();
6348 6d946cda aurel32
#endif
6349 e9009676 bellard
        gdb_exit(cpu_env, arg1);
6350 ec86b0fb bellard
        ret = get_errno(exit_group(arg1));
6351 ec86b0fb bellard
        break;
6352 ec86b0fb bellard
#endif
6353 31e31b8a bellard
    case TARGET_NR_setdomainname:
6354 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6355 579a97f7 bellard
            goto efault;
6356 53a5960a pbrook
        ret = get_errno(setdomainname(p, arg2));
6357 53a5960a pbrook
        unlock_user(p, arg1, 0);
6358 31e31b8a bellard
        break;
6359 31e31b8a bellard
    case TARGET_NR_uname:
6360 31e31b8a bellard
        /* no need to transcode because we use the linux syscall */
6361 29e619b1 bellard
        {
6362 29e619b1 bellard
            struct new_utsname * buf;
6363 3b46e624 ths
6364 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, buf, arg1, 0))
6365 579a97f7 bellard
                goto efault;
6366 29e619b1 bellard
            ret = get_errno(sys_uname(buf));
6367 29e619b1 bellard
            if (!is_error(ret)) {
6368 29e619b1 bellard
                /* Overrite the native machine name with whatever is being
6369 29e619b1 bellard
                   emulated. */
6370 da79030f Loïc Minier
                strcpy (buf->machine, cpu_to_uname_machine(cpu_env));
6371 c5937220 pbrook
                /* Allow the user to override the reported release.  */
6372 c5937220 pbrook
                if (qemu_uname_release && *qemu_uname_release)
6373 c5937220 pbrook
                  strcpy (buf->release, qemu_uname_release);
6374 29e619b1 bellard
            }
6375 53a5960a pbrook
            unlock_user_struct(buf, arg1, 1);
6376 29e619b1 bellard
        }
6377 31e31b8a bellard
        break;
6378 6dbad63e bellard
#ifdef TARGET_I386
6379 31e31b8a bellard
    case TARGET_NR_modify_ldt:
6380 03acab66 bellard
        ret = do_modify_ldt(cpu_env, arg1, arg2, arg3);
6381 5cd4393b bellard
        break;
6382 84409ddb j_mayer
#if !defined(TARGET_X86_64)
6383 5cd4393b bellard
    case TARGET_NR_vm86old:
6384 5cd4393b bellard
        goto unimplemented;
6385 5cd4393b bellard
    case TARGET_NR_vm86:
6386 53a5960a pbrook
        ret = do_vm86(cpu_env, arg1, arg2);
6387 6dbad63e bellard
        break;
6388 6dbad63e bellard
#endif
6389 84409ddb j_mayer
#endif
6390 31e31b8a bellard
    case TARGET_NR_adjtimex:
6391 31e31b8a bellard
        goto unimplemented;
6392 e5febef5 ths
#ifdef TARGET_NR_create_module
6393 31e31b8a bellard
    case TARGET_NR_create_module:
6394 e5febef5 ths
#endif
6395 31e31b8a bellard
    case TARGET_NR_init_module:
6396 31e31b8a bellard
    case TARGET_NR_delete_module:
6397 e5febef5 ths
#ifdef TARGET_NR_get_kernel_syms
6398 31e31b8a bellard
    case TARGET_NR_get_kernel_syms:
6399 e5febef5 ths
#endif
6400 31e31b8a bellard
        goto unimplemented;
6401 31e31b8a bellard
    case TARGET_NR_quotactl:
6402 31e31b8a bellard
        goto unimplemented;
6403 31e31b8a bellard
    case TARGET_NR_getpgid:
6404 31e31b8a bellard
        ret = get_errno(getpgid(arg1));
6405 31e31b8a bellard
        break;
6406 31e31b8a bellard
    case TARGET_NR_fchdir:
6407 31e31b8a bellard
        ret = get_errno(fchdir(arg1));
6408 31e31b8a bellard
        break;
6409 84409ddb j_mayer
#ifdef TARGET_NR_bdflush /* not on x86_64 */
6410 31e31b8a bellard
    case TARGET_NR_bdflush:
6411 31e31b8a bellard
        goto unimplemented;
6412 84409ddb j_mayer
#endif
6413 e5febef5 ths
#ifdef TARGET_NR_sysfs
6414 31e31b8a bellard
    case TARGET_NR_sysfs:
6415 31e31b8a bellard
        goto unimplemented;
6416 e5febef5 ths
#endif
6417 31e31b8a bellard
    case TARGET_NR_personality:
6418 1b6b029e bellard
        ret = get_errno(personality(arg1));
6419 31e31b8a bellard
        break;
6420 e5febef5 ths
#ifdef TARGET_NR_afs_syscall
6421 31e31b8a bellard
    case TARGET_NR_afs_syscall:
6422 31e31b8a bellard
        goto unimplemented;
6423 e5febef5 ths
#endif
6424 7a3148a9 j_mayer
#ifdef TARGET_NR__llseek /* Not on alpha */
6425 31e31b8a bellard
    case TARGET_NR__llseek:
6426 31e31b8a bellard
        {
6427 0c1592d9 Peter Maydell
            int64_t res;
6428 d35b261c Richard Henderson
#if !defined(__NR_llseek)
6429 0c1592d9 Peter Maydell
            res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
6430 0c1592d9 Peter Maydell
            if (res == -1) {
6431 0c1592d9 Peter Maydell
                ret = get_errno(res);
6432 0c1592d9 Peter Maydell
            } else {
6433 0c1592d9 Peter Maydell
                ret = 0;
6434 0c1592d9 Peter Maydell
            }
6435 4f2ac237 bellard
#else
6436 31e31b8a bellard
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
6437 4f2ac237 bellard
#endif
6438 0c1592d9 Peter Maydell
            if ((ret == 0) && put_user_s64(res, arg4)) {
6439 0c1592d9 Peter Maydell
                goto efault;
6440 0c1592d9 Peter Maydell
            }
6441 31e31b8a bellard
        }
6442 31e31b8a bellard
        break;
6443 7a3148a9 j_mayer
#endif
6444 31e31b8a bellard
    case TARGET_NR_getdents:
6445 d83c8733 Ulrich Hecht
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
6446 4add45b4 bellard
        {
6447 53a5960a pbrook
            struct target_dirent *target_dirp;
6448 6556a833 aurel32
            struct linux_dirent *dirp;
6449 992f48a0 blueswir1
            abi_long count = arg3;
6450 4add45b4 bellard
6451 4add45b4 bellard
            dirp = malloc(count);
6452 0da46a6e ths
            if (!dirp) {
6453 579a97f7 bellard
                ret = -TARGET_ENOMEM;
6454 0da46a6e ths
                goto fail;
6455 0da46a6e ths
            }
6456 3b46e624 ths
6457 4add45b4 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
6458 4add45b4 bellard
            if (!is_error(ret)) {
6459 6556a833 aurel32
                struct linux_dirent *de;
6460 4add45b4 bellard
                struct target_dirent *tde;
6461 4add45b4 bellard
                int len = ret;
6462 4add45b4 bellard
                int reclen, treclen;
6463 4add45b4 bellard
                int count1, tnamelen;
6464 4add45b4 bellard
6465 4add45b4 bellard
                count1 = 0;
6466 4add45b4 bellard
                de = dirp;
6467 579a97f7 bellard
                if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6468 579a97f7 bellard
                    goto efault;
6469 4add45b4 bellard
                tde = target_dirp;
6470 4add45b4 bellard
                while (len > 0) {
6471 4add45b4 bellard
                    reclen = de->d_reclen;
6472 992f48a0 blueswir1
                    treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
6473 4add45b4 bellard
                    tde->d_reclen = tswap16(treclen);
6474 4add45b4 bellard
                    tde->d_ino = tswapl(de->d_ino);
6475 4add45b4 bellard
                    tde->d_off = tswapl(de->d_off);
6476 992f48a0 blueswir1
                    tnamelen = treclen - (2 * sizeof(abi_long) + 2);
6477 4add45b4 bellard
                    if (tnamelen > 256)
6478 4add45b4 bellard
                        tnamelen = 256;
6479 80a9d035 bellard
                    /* XXX: may not be correct */
6480 be15b141 blueswir1
                    pstrcpy(tde->d_name, tnamelen, de->d_name);
6481 6556a833 aurel32
                    de = (struct linux_dirent *)((char *)de + reclen);
6482 4add45b4 bellard
                    len -= reclen;
6483 1c5bf3bf j_mayer
                    tde = (struct target_dirent *)((char *)tde + treclen);
6484 4add45b4 bellard
                    count1 += treclen;
6485 4add45b4 bellard
                }
6486 4add45b4 bellard
                ret = count1;
6487 579a97f7 bellard
                unlock_user(target_dirp, arg2, ret);
6488 4add45b4 bellard
            }
6489 4add45b4 bellard
            free(dirp);
6490 4add45b4 bellard
        }
6491 4add45b4 bellard
#else
6492 31e31b8a bellard
        {
6493 6556a833 aurel32
            struct linux_dirent *dirp;
6494 992f48a0 blueswir1
            abi_long count = arg3;
6495 dab2ed99 bellard
6496 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6497 579a97f7 bellard
                goto efault;
6498 72f03900 bellard
            ret = get_errno(sys_getdents(arg1, dirp, count));
6499 31e31b8a bellard
            if (!is_error(ret)) {
6500 6556a833 aurel32
                struct linux_dirent *de;
6501 31e31b8a bellard
                int len = ret;
6502 31e31b8a bellard
                int reclen;
6503 31e31b8a bellard
                de = dirp;
6504 31e31b8a bellard
                while (len > 0) {
6505 8083a3e5 bellard
                    reclen = de->d_reclen;
6506 31e31b8a bellard
                    if (reclen > len)
6507 31e31b8a bellard
                        break;
6508 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
6509 31e31b8a bellard
                    tswapls(&de->d_ino);
6510 31e31b8a bellard
                    tswapls(&de->d_off);
6511 6556a833 aurel32
                    de = (struct linux_dirent *)((char *)de + reclen);
6512 31e31b8a bellard
                    len -= reclen;
6513 31e31b8a bellard
                }
6514 31e31b8a bellard
            }
6515 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
6516 31e31b8a bellard
        }
6517 4add45b4 bellard
#endif
6518 31e31b8a bellard
        break;
6519 3ae43202 ths
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
6520 dab2ed99 bellard
    case TARGET_NR_getdents64:
6521 dab2ed99 bellard
        {
6522 6556a833 aurel32
            struct linux_dirent64 *dirp;
6523 992f48a0 blueswir1
            abi_long count = arg3;
6524 579a97f7 bellard
            if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
6525 579a97f7 bellard
                goto efault;
6526 dab2ed99 bellard
            ret = get_errno(sys_getdents64(arg1, dirp, count));
6527 dab2ed99 bellard
            if (!is_error(ret)) {
6528 6556a833 aurel32
                struct linux_dirent64 *de;
6529 dab2ed99 bellard
                int len = ret;
6530 dab2ed99 bellard
                int reclen;
6531 dab2ed99 bellard
                de = dirp;
6532 dab2ed99 bellard
                while (len > 0) {
6533 8083a3e5 bellard
                    reclen = de->d_reclen;
6534 dab2ed99 bellard
                    if (reclen > len)
6535 dab2ed99 bellard
                        break;
6536 8083a3e5 bellard
                    de->d_reclen = tswap16(reclen);
6537 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_ino);
6538 8582a53a bellard
                    tswap64s((uint64_t *)&de->d_off);
6539 6556a833 aurel32
                    de = (struct linux_dirent64 *)((char *)de + reclen);
6540 dab2ed99 bellard
                    len -= reclen;
6541 dab2ed99 bellard
                }
6542 dab2ed99 bellard
            }
6543 53a5960a pbrook
            unlock_user(dirp, arg2, ret);
6544 dab2ed99 bellard
        }
6545 dab2ed99 bellard
        break;
6546 a541f297 bellard
#endif /* TARGET_NR_getdents64 */
6547 a4c075f1 Ulrich Hecht
#if defined(TARGET_NR__newselect) || defined(TARGET_S390X)
6548 a4c075f1 Ulrich Hecht
#ifdef TARGET_S390X
6549 a4c075f1 Ulrich Hecht
    case TARGET_NR_select:
6550 a4c075f1 Ulrich Hecht
#else
6551 31e31b8a bellard
    case TARGET_NR__newselect:
6552 a4c075f1 Ulrich Hecht
#endif
6553 53a5960a pbrook
        ret = do_select(arg1, arg2, arg3, arg4, arg5);
6554 31e31b8a bellard
        break;
6555 e5febef5 ths
#endif
6556 d8035d4c Mike Frysinger
#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll)
6557 d8035d4c Mike Frysinger
# ifdef TARGET_NR_poll
6558 9de5e440 bellard
    case TARGET_NR_poll:
6559 d8035d4c Mike Frysinger
# endif
6560 d8035d4c Mike Frysinger
# ifdef TARGET_NR_ppoll
6561 d8035d4c Mike Frysinger
    case TARGET_NR_ppoll:
6562 d8035d4c Mike Frysinger
# endif
6563 9de5e440 bellard
        {
6564 53a5960a pbrook
            struct target_pollfd *target_pfd;
6565 9de5e440 bellard
            unsigned int nfds = arg2;
6566 9de5e440 bellard
            int timeout = arg3;
6567 9de5e440 bellard
            struct pollfd *pfd;
6568 7854b056 bellard
            unsigned int i;
6569 9de5e440 bellard
6570 579a97f7 bellard
            target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1);
6571 579a97f7 bellard
            if (!target_pfd)
6572 579a97f7 bellard
                goto efault;
6573 d8035d4c Mike Frysinger
6574 9de5e440 bellard
            pfd = alloca(sizeof(struct pollfd) * nfds);
6575 9de5e440 bellard
            for(i = 0; i < nfds; i++) {
6576 5cd4393b bellard
                pfd[i].fd = tswap32(target_pfd[i].fd);
6577 5cd4393b bellard
                pfd[i].events = tswap16(target_pfd[i].events);
6578 9de5e440 bellard
            }
6579 d8035d4c Mike Frysinger
6580 d8035d4c Mike Frysinger
# ifdef TARGET_NR_ppoll
6581 d8035d4c Mike Frysinger
            if (num == TARGET_NR_ppoll) {
6582 d8035d4c Mike Frysinger
                struct timespec _timeout_ts, *timeout_ts = &_timeout_ts;
6583 d8035d4c Mike Frysinger
                target_sigset_t *target_set;
6584 d8035d4c Mike Frysinger
                sigset_t _set, *set = &_set;
6585 d8035d4c Mike Frysinger
6586 d8035d4c Mike Frysinger
                if (arg3) {
6587 d8035d4c Mike Frysinger
                    if (target_to_host_timespec(timeout_ts, arg3)) {
6588 d8035d4c Mike Frysinger
                        unlock_user(target_pfd, arg1, 0);
6589 d8035d4c Mike Frysinger
                        goto efault;
6590 d8035d4c Mike Frysinger
                    }
6591 d8035d4c Mike Frysinger
                } else {
6592 d8035d4c Mike Frysinger
                    timeout_ts = NULL;
6593 d8035d4c Mike Frysinger
                }
6594 d8035d4c Mike Frysinger
6595 d8035d4c Mike Frysinger
                if (arg4) {
6596 d8035d4c Mike Frysinger
                    target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
6597 d8035d4c Mike Frysinger
                    if (!target_set) {
6598 d8035d4c Mike Frysinger
                        unlock_user(target_pfd, arg1, 0);
6599 d8035d4c Mike Frysinger
                        goto efault;
6600 d8035d4c Mike Frysinger
                    }
6601 d8035d4c Mike Frysinger
                    target_to_host_sigset(set, target_set);
6602 d8035d4c Mike Frysinger
                } else {
6603 d8035d4c Mike Frysinger
                    set = NULL;
6604 d8035d4c Mike Frysinger
                }
6605 d8035d4c Mike Frysinger
6606 d8035d4c Mike Frysinger
                ret = get_errno(sys_ppoll(pfd, nfds, timeout_ts, set, _NSIG/8));
6607 d8035d4c Mike Frysinger
6608 d8035d4c Mike Frysinger
                if (!is_error(ret) && arg3) {
6609 d8035d4c Mike Frysinger
                    host_to_target_timespec(arg3, timeout_ts);
6610 d8035d4c Mike Frysinger
                }
6611 d8035d4c Mike Frysinger
                if (arg4) {
6612 d8035d4c Mike Frysinger
                    unlock_user(target_set, arg4, 0);
6613 d8035d4c Mike Frysinger
                }
6614 d8035d4c Mike Frysinger
            } else
6615 d8035d4c Mike Frysinger
# endif
6616 d8035d4c Mike Frysinger
                ret = get_errno(poll(pfd, nfds, timeout));
6617 d8035d4c Mike Frysinger
6618 9de5e440 bellard
            if (!is_error(ret)) {
6619 9de5e440 bellard
                for(i = 0; i < nfds; i++) {
6620 5cd4393b bellard
                    target_pfd[i].revents = tswap16(pfd[i].revents);
6621 9de5e440 bellard
                }
6622 9de5e440 bellard
            }
6623 30cb4cde Peter Maydell
            unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds);
6624 9de5e440 bellard
        }
6625 9de5e440 bellard
        break;
6626 e5febef5 ths
#endif
6627 31e31b8a bellard
    case TARGET_NR_flock:
6628 9de5e440 bellard
        /* NOTE: the flock constant seems to be the same for every
6629 9de5e440 bellard
           Linux platform */
6630 9de5e440 bellard
        ret = get_errno(flock(arg1, arg2));
6631 31e31b8a bellard
        break;
6632 31e31b8a bellard
    case TARGET_NR_readv:
6633 31e31b8a bellard
        {
6634 31e31b8a bellard
            int count = arg3;
6635 31e31b8a bellard
            struct iovec *vec;
6636 31e31b8a bellard
6637 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
6638 41df8411 bellard
            if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0)
6639 41df8411 bellard
                goto efault;
6640 31e31b8a bellard
            ret = get_errno(readv(arg1, vec, count));
6641 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 1);
6642 31e31b8a bellard
        }
6643 31e31b8a bellard
        break;
6644 31e31b8a bellard
    case TARGET_NR_writev:
6645 31e31b8a bellard
        {
6646 31e31b8a bellard
            int count = arg3;
6647 31e31b8a bellard
            struct iovec *vec;
6648 31e31b8a bellard
6649 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
6650 41df8411 bellard
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
6651 41df8411 bellard
                goto efault;
6652 31e31b8a bellard
            ret = get_errno(writev(arg1, vec, count));
6653 53a5960a pbrook
            unlock_iovec(vec, arg2, count, 0);
6654 31e31b8a bellard
        }
6655 31e31b8a bellard
        break;
6656 31e31b8a bellard
    case TARGET_NR_getsid:
6657 31e31b8a bellard
        ret = get_errno(getsid(arg1));
6658 31e31b8a bellard
        break;
6659 7a3148a9 j_mayer
#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
6660 31e31b8a bellard
    case TARGET_NR_fdatasync:
6661 5cd4393b bellard
        ret = get_errno(fdatasync(arg1));
6662 5cd4393b bellard
        break;
6663 7a3148a9 j_mayer
#endif
6664 31e31b8a bellard
    case TARGET_NR__sysctl:
6665 0da46a6e ths
        /* We don't implement this, but ENOTDIR is always a safe
6666 29e619b1 bellard
           return value. */
6667 0da46a6e ths
        ret = -TARGET_ENOTDIR;
6668 0da46a6e ths
        break;
6669 737de1d1 Mike Frysinger
    case TARGET_NR_sched_getaffinity:
6670 737de1d1 Mike Frysinger
        {
6671 737de1d1 Mike Frysinger
            unsigned int mask_size;
6672 737de1d1 Mike Frysinger
            unsigned long *mask;
6673 737de1d1 Mike Frysinger
6674 737de1d1 Mike Frysinger
            /*
6675 737de1d1 Mike Frysinger
             * sched_getaffinity needs multiples of ulong, so need to take
6676 737de1d1 Mike Frysinger
             * care of mismatches between target ulong and host ulong sizes.
6677 737de1d1 Mike Frysinger
             */
6678 737de1d1 Mike Frysinger
            if (arg2 & (sizeof(abi_ulong) - 1)) {
6679 737de1d1 Mike Frysinger
                ret = -TARGET_EINVAL;
6680 737de1d1 Mike Frysinger
                break;
6681 737de1d1 Mike Frysinger
            }
6682 737de1d1 Mike Frysinger
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
6683 737de1d1 Mike Frysinger
6684 737de1d1 Mike Frysinger
            mask = alloca(mask_size);
6685 737de1d1 Mike Frysinger
            ret = get_errno(sys_sched_getaffinity(arg1, mask_size, mask));
6686 737de1d1 Mike Frysinger
6687 737de1d1 Mike Frysinger
            if (!is_error(ret)) {
6688 cd18f05e Mike McCormack
                if (copy_to_user(arg3, mask, ret)) {
6689 737de1d1 Mike Frysinger
                    goto efault;
6690 737de1d1 Mike Frysinger
                }
6691 737de1d1 Mike Frysinger
            }
6692 737de1d1 Mike Frysinger
        }
6693 737de1d1 Mike Frysinger
        break;
6694 737de1d1 Mike Frysinger
    case TARGET_NR_sched_setaffinity:
6695 737de1d1 Mike Frysinger
        {
6696 737de1d1 Mike Frysinger
            unsigned int mask_size;
6697 737de1d1 Mike Frysinger
            unsigned long *mask;
6698 737de1d1 Mike Frysinger
6699 737de1d1 Mike Frysinger
            /*
6700 737de1d1 Mike Frysinger
             * sched_setaffinity needs multiples of ulong, so need to take
6701 737de1d1 Mike Frysinger
             * care of mismatches between target ulong and host ulong sizes.
6702 737de1d1 Mike Frysinger
             */
6703 737de1d1 Mike Frysinger
            if (arg2 & (sizeof(abi_ulong) - 1)) {
6704 737de1d1 Mike Frysinger
                ret = -TARGET_EINVAL;
6705 737de1d1 Mike Frysinger
                break;
6706 737de1d1 Mike Frysinger
            }
6707 737de1d1 Mike Frysinger
            mask_size = (arg2 + (sizeof(*mask) - 1)) & ~(sizeof(*mask) - 1);
6708 737de1d1 Mike Frysinger
6709 737de1d1 Mike Frysinger
            mask = alloca(mask_size);
6710 737de1d1 Mike Frysinger
            if (!lock_user_struct(VERIFY_READ, p, arg3, 1)) {
6711 737de1d1 Mike Frysinger
                goto efault;
6712 737de1d1 Mike Frysinger
            }
6713 737de1d1 Mike Frysinger
            memcpy(mask, p, arg2);
6714 737de1d1 Mike Frysinger
            unlock_user_struct(p, arg2, 0);
6715 737de1d1 Mike Frysinger
6716 737de1d1 Mike Frysinger
            ret = get_errno(sys_sched_setaffinity(arg1, mask_size, mask));
6717 737de1d1 Mike Frysinger
        }
6718 737de1d1 Mike Frysinger
        break;
6719 31e31b8a bellard
    case TARGET_NR_sched_setparam:
6720 5cd4393b bellard
        {
6721 53a5960a pbrook
            struct sched_param *target_schp;
6722 5cd4393b bellard
            struct sched_param schp;
6723 53a5960a pbrook
6724 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
6725 579a97f7 bellard
                goto efault;
6726 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
6727 53a5960a pbrook
            unlock_user_struct(target_schp, arg2, 0);
6728 5cd4393b bellard
            ret = get_errno(sched_setparam(arg1, &schp));
6729 5cd4393b bellard
        }
6730 5cd4393b bellard
        break;
6731 31e31b8a bellard
    case TARGET_NR_sched_getparam:
6732 5cd4393b bellard
        {
6733 53a5960a pbrook
            struct sched_param *target_schp;
6734 5cd4393b bellard
            struct sched_param schp;
6735 5cd4393b bellard
            ret = get_errno(sched_getparam(arg1, &schp));
6736 5cd4393b bellard
            if (!is_error(ret)) {
6737 579a97f7 bellard
                if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
6738 579a97f7 bellard
                    goto efault;
6739 5cd4393b bellard
                target_schp->sched_priority = tswap32(schp.sched_priority);
6740 53a5960a pbrook
                unlock_user_struct(target_schp, arg2, 1);
6741 5cd4393b bellard
            }
6742 5cd4393b bellard
        }
6743 5cd4393b bellard
        break;
6744 31e31b8a bellard
    case TARGET_NR_sched_setscheduler:
6745 5cd4393b bellard
        {
6746 53a5960a pbrook
            struct sched_param *target_schp;
6747 5cd4393b bellard
            struct sched_param schp;
6748 579a97f7 bellard
            if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
6749 579a97f7 bellard
                goto efault;
6750 5cd4393b bellard
            schp.sched_priority = tswap32(target_schp->sched_priority);
6751 53a5960a pbrook
            unlock_user_struct(target_schp, arg3, 0);
6752 5cd4393b bellard
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
6753 5cd4393b bellard
        }
6754 5cd4393b bellard
        break;
6755 31e31b8a bellard
    case TARGET_NR_sched_getscheduler:
6756 5cd4393b bellard
        ret = get_errno(sched_getscheduler(arg1));
6757 5cd4393b bellard
        break;
6758 31e31b8a bellard
    case TARGET_NR_sched_yield:
6759 31e31b8a bellard
        ret = get_errno(sched_yield());
6760 31e31b8a bellard
        break;
6761 31e31b8a bellard
    case TARGET_NR_sched_get_priority_max:
6762 5cd4393b bellard
        ret = get_errno(sched_get_priority_max(arg1));
6763 5cd4393b bellard
        break;
6764 31e31b8a bellard
    case TARGET_NR_sched_get_priority_min:
6765 5cd4393b bellard
        ret = get_errno(sched_get_priority_min(arg1));
6766 5cd4393b bellard
        break;
6767 31e31b8a bellard
    case TARGET_NR_sched_rr_get_interval:
6768 5cd4393b bellard
        {
6769 5cd4393b bellard
            struct timespec ts;
6770 5cd4393b bellard
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
6771 5cd4393b bellard
            if (!is_error(ret)) {
6772 53a5960a pbrook
                host_to_target_timespec(arg2, &ts);
6773 5cd4393b bellard
            }
6774 5cd4393b bellard
        }
6775 5cd4393b bellard
        break;
6776 31e31b8a bellard
    case TARGET_NR_nanosleep:
6777 1b6b029e bellard
        {
6778 1b6b029e bellard
            struct timespec req, rem;
6779 53a5960a pbrook
            target_to_host_timespec(&req, arg1);
6780 1b6b029e bellard
            ret = get_errno(nanosleep(&req, &rem));
6781 53a5960a pbrook
            if (is_error(ret) && arg2) {
6782 53a5960a pbrook
                host_to_target_timespec(arg2, &rem);
6783 1b6b029e bellard
            }
6784 1b6b029e bellard
        }
6785 1b6b029e bellard
        break;
6786 e5febef5 ths
#ifdef TARGET_NR_query_module
6787 31e31b8a bellard
    case TARGET_NR_query_module:
6788 5cd4393b bellard
        goto unimplemented;
6789 e5febef5 ths
#endif
6790 e5febef5 ths
#ifdef TARGET_NR_nfsservctl
6791 31e31b8a bellard
    case TARGET_NR_nfsservctl:
6792 5cd4393b bellard
        goto unimplemented;
6793 e5febef5 ths
#endif
6794 31e31b8a bellard
    case TARGET_NR_prctl:
6795 e5574487 ths
        switch (arg1)
6796 e5574487 ths
            {
6797 e5574487 ths
            case PR_GET_PDEATHSIG:
6798 e5574487 ths
                {
6799 e5574487 ths
                    int deathsig;
6800 e5574487 ths
                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
6801 2f619698 bellard
                    if (!is_error(ret) && arg2
6802 2f619698 bellard
                        && put_user_ual(deathsig, arg2))
6803 2f619698 bellard
                        goto efault;
6804 e5574487 ths
                }
6805 e5574487 ths
                break;
6806 e5574487 ths
            default:
6807 e5574487 ths
                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
6808 e5574487 ths
                break;
6809 e5574487 ths
            }
6810 39b9aae1 ths
        break;
6811 d2fd1af7 bellard
#ifdef TARGET_NR_arch_prctl
6812 d2fd1af7 bellard
    case TARGET_NR_arch_prctl:
6813 d2fd1af7 bellard
#if defined(TARGET_I386) && !defined(TARGET_ABI32)
6814 d2fd1af7 bellard
        ret = do_arch_prctl(cpu_env, arg1, arg2);
6815 d2fd1af7 bellard
        break;
6816 d2fd1af7 bellard
#else
6817 d2fd1af7 bellard
        goto unimplemented;
6818 d2fd1af7 bellard
#endif
6819 d2fd1af7 bellard
#endif
6820 67867308 bellard
#ifdef TARGET_NR_pread
6821 31e31b8a bellard
    case TARGET_NR_pread:
6822 a4ae00bc balrog
#ifdef TARGET_ARM
6823 a4ae00bc balrog
        if (((CPUARMState *)cpu_env)->eabi)
6824 a4ae00bc balrog
            arg4 = arg5;
6825 a4ae00bc balrog
#endif
6826 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6827 579a97f7 bellard
            goto efault;
6828 53a5960a pbrook
        ret = get_errno(pread(arg1, p, arg3, arg4));
6829 53a5960a pbrook
        unlock_user(p, arg2, ret);
6830 206f0fa7 bellard
        break;
6831 31e31b8a bellard
    case TARGET_NR_pwrite:
6832 a4ae00bc balrog
#ifdef TARGET_ARM
6833 a4ae00bc balrog
        if (((CPUARMState *)cpu_env)->eabi)
6834 a4ae00bc balrog
            arg4 = arg5;
6835 a4ae00bc balrog
#endif
6836 579a97f7 bellard
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6837 579a97f7 bellard
            goto efault;
6838 53a5960a pbrook
        ret = get_errno(pwrite(arg1, p, arg3, arg4));
6839 53a5960a pbrook
        unlock_user(p, arg2, 0);
6840 206f0fa7 bellard
        break;
6841 67867308 bellard
#endif
6842 f2c7ba15 aurel32
#ifdef TARGET_NR_pread64
6843 f2c7ba15 aurel32
    case TARGET_NR_pread64:
6844 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
6845 f2c7ba15 aurel32
            goto efault;
6846 f2c7ba15 aurel32
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
6847 f2c7ba15 aurel32
        unlock_user(p, arg2, ret);
6848 f2c7ba15 aurel32
        break;
6849 f2c7ba15 aurel32
    case TARGET_NR_pwrite64:
6850 f2c7ba15 aurel32
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
6851 f2c7ba15 aurel32
            goto efault;
6852 f2c7ba15 aurel32
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
6853 f2c7ba15 aurel32
        unlock_user(p, arg2, 0);
6854 f2c7ba15 aurel32
        break;
6855 f2c7ba15 aurel32
#endif
6856 31e31b8a bellard
    case TARGET_NR_getcwd:
6857 579a97f7 bellard
        if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0)))
6858 579a97f7 bellard
            goto efault;
6859 53a5960a pbrook
        ret = get_errno(sys_getcwd1(p, arg2));
6860 53a5960a pbrook
        unlock_user(p, arg1, ret);
6861 31e31b8a bellard
        break;
6862 31e31b8a bellard
    case TARGET_NR_capget:
6863 5cd4393b bellard
        goto unimplemented;
6864 31e31b8a bellard
    case TARGET_NR_capset:
6865 5cd4393b bellard
        goto unimplemented;
6866 31e31b8a bellard
    case TARGET_NR_sigaltstack:
6867 198a74de ths
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_MIPS) || \
6868 c761c154 Laurent Vivier
    defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_ALPHA) || \
6869 a4c075f1 Ulrich Hecht
    defined(TARGET_M68K) || defined(TARGET_S390X)
6870 579a97f7 bellard
        ret = do_sigaltstack(arg1, arg2, get_sp_from_cpustate((CPUState *)cpu_env));
6871 a04e134a ths
        break;
6872 a04e134a ths
#else
6873 5cd4393b bellard
        goto unimplemented;
6874 a04e134a ths
#endif
6875 31e31b8a bellard
    case TARGET_NR_sendfile:
6876 5cd4393b bellard
        goto unimplemented;
6877 ebc05488 bellard
#ifdef TARGET_NR_getpmsg
6878 31e31b8a bellard
    case TARGET_NR_getpmsg:
6879 5cd4393b bellard
        goto unimplemented;
6880 ebc05488 bellard
#endif
6881 ebc05488 bellard
#ifdef TARGET_NR_putpmsg
6882 31e31b8a bellard
    case TARGET_NR_putpmsg:
6883 5cd4393b bellard
        goto unimplemented;
6884 ebc05488 bellard
#endif
6885 048f6b4d bellard
#ifdef TARGET_NR_vfork
6886 31e31b8a bellard
    case TARGET_NR_vfork:
6887 d865bab5 pbrook
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD,
6888 d865bab5 pbrook
                        0, 0, 0, 0));
6889 31e31b8a bellard
        break;
6890 048f6b4d bellard
#endif
6891 ebc05488 bellard
#ifdef TARGET_NR_ugetrlimit
6892 31e31b8a bellard
    case TARGET_NR_ugetrlimit:
6893 728584be bellard
    {
6894 728584be bellard
        struct rlimit rlim;
6895 728584be bellard
        ret = get_errno(getrlimit(arg1, &rlim));
6896 728584be bellard
        if (!is_error(ret)) {
6897 53a5960a pbrook
            struct target_rlimit *target_rlim;
6898 579a97f7 bellard
            if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0))
6899 579a97f7 bellard
                goto efault;
6900 81bbe906 takasi-y@ops.dti.ne.jp
            target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur);
6901 81bbe906 takasi-y@ops.dti.ne.jp
            target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max);
6902 53a5960a pbrook
            unlock_user_struct(target_rlim, arg2, 1);
6903 728584be bellard
        }
6904 728584be bellard
        break;
6905 728584be bellard
    }
6906 ebc05488 bellard
#endif
6907 a315a145 bellard
#ifdef TARGET_NR_truncate64
6908 31e31b8a bellard
    case TARGET_NR_truncate64:
6909 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6910 579a97f7 bellard
            goto efault;
6911 53a5960a pbrook
        ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
6912 53a5960a pbrook
        unlock_user(p, arg1, 0);
6913 667f38b1 bellard
        break;
6914 a315a145 bellard
#endif
6915 a315a145 bellard
#ifdef TARGET_NR_ftruncate64
6916 31e31b8a bellard
    case TARGET_NR_ftruncate64:
6917 ce4defa0 pbrook
        ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
6918 667f38b1 bellard
        break;
6919 a315a145 bellard
#endif
6920 a315a145 bellard
#ifdef TARGET_NR_stat64
6921 31e31b8a bellard
    case TARGET_NR_stat64:
6922 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6923 579a97f7 bellard
            goto efault;
6924 53a5960a pbrook
        ret = get_errno(stat(path(p), &st));
6925 53a5960a pbrook
        unlock_user(p, arg1, 0);
6926 6a24a778 balrog
        if (!is_error(ret))
6927 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6928 6a24a778 balrog
        break;
6929 a315a145 bellard
#endif
6930 a315a145 bellard
#ifdef TARGET_NR_lstat64
6931 31e31b8a bellard
    case TARGET_NR_lstat64:
6932 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6933 579a97f7 bellard
            goto efault;
6934 53a5960a pbrook
        ret = get_errno(lstat(path(p), &st));
6935 53a5960a pbrook
        unlock_user(p, arg1, 0);
6936 6a24a778 balrog
        if (!is_error(ret))
6937 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6938 6a24a778 balrog
        break;
6939 a315a145 bellard
#endif
6940 a315a145 bellard
#ifdef TARGET_NR_fstat64
6941 31e31b8a bellard
    case TARGET_NR_fstat64:
6942 6a24a778 balrog
        ret = get_errno(fstat(arg1, &st));
6943 6a24a778 balrog
        if (!is_error(ret))
6944 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg2, &st);
6945 6a24a778 balrog
        break;
6946 ce4defa0 pbrook
#endif
6947 9d33b76b aurel32
#if (defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)) && \
6948 9d33b76b aurel32
        (defined(__NR_fstatat64) || defined(__NR_newfstatat))
6949 9d33b76b aurel32
#ifdef TARGET_NR_fstatat64
6950 6a24a778 balrog
    case TARGET_NR_fstatat64:
6951 9d33b76b aurel32
#endif
6952 9d33b76b aurel32
#ifdef TARGET_NR_newfstatat
6953 9d33b76b aurel32
    case TARGET_NR_newfstatat:
6954 9d33b76b aurel32
#endif
6955 6a24a778 balrog
        if (!(p = lock_user_string(arg2)))
6956 6a24a778 balrog
            goto efault;
6957 9d33b76b aurel32
#ifdef __NR_fstatat64
6958 6a24a778 balrog
        ret = get_errno(sys_fstatat64(arg1, path(p), &st, arg4));
6959 9d33b76b aurel32
#else
6960 9d33b76b aurel32
        ret = get_errno(sys_newfstatat(arg1, path(p), &st, arg4));
6961 9d33b76b aurel32
#endif
6962 6a24a778 balrog
        if (!is_error(ret))
6963 6a24a778 balrog
            ret = host_to_target_stat64(cpu_env, arg3, &st);
6964 60cd49d5 bellard
        break;
6965 a315a145 bellard
#endif
6966 67867308 bellard
    case TARGET_NR_lchown:
6967 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
6968 579a97f7 bellard
            goto efault;
6969 53a5960a pbrook
        ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
6970 53a5960a pbrook
        unlock_user(p, arg1, 0);
6971 67867308 bellard
        break;
6972 0c866a7e Riku Voipio
#ifdef TARGET_NR_getuid
6973 67867308 bellard
    case TARGET_NR_getuid:
6974 67867308 bellard
        ret = get_errno(high2lowuid(getuid()));
6975 67867308 bellard
        break;
6976 0c866a7e Riku Voipio
#endif
6977 0c866a7e Riku Voipio
#ifdef TARGET_NR_getgid
6978 67867308 bellard
    case TARGET_NR_getgid:
6979 67867308 bellard
        ret = get_errno(high2lowgid(getgid()));
6980 67867308 bellard
        break;
6981 0c866a7e Riku Voipio
#endif
6982 0c866a7e Riku Voipio
#ifdef TARGET_NR_geteuid
6983 67867308 bellard
    case TARGET_NR_geteuid:
6984 67867308 bellard
        ret = get_errno(high2lowuid(geteuid()));
6985 67867308 bellard
        break;
6986 0c866a7e Riku Voipio
#endif
6987 0c866a7e Riku Voipio
#ifdef TARGET_NR_getegid
6988 67867308 bellard
    case TARGET_NR_getegid:
6989 67867308 bellard
        ret = get_errno(high2lowgid(getegid()));
6990 67867308 bellard
        break;
6991 0c866a7e Riku Voipio
#endif
6992 67867308 bellard
    case TARGET_NR_setreuid:
6993 67867308 bellard
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
6994 67867308 bellard
        break;
6995 67867308 bellard
    case TARGET_NR_setregid:
6996 67867308 bellard
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
6997 67867308 bellard
        break;
6998 67867308 bellard
    case TARGET_NR_getgroups:
6999 67867308 bellard
        {
7000 67867308 bellard
            int gidsetsize = arg1;
7001 0c866a7e Riku Voipio
            target_id *target_grouplist;
7002 67867308 bellard
            gid_t *grouplist;
7003 67867308 bellard
            int i;
7004 67867308 bellard
7005 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7006 67867308 bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
7007 cb3bc233 balrog
            if (gidsetsize == 0)
7008 cb3bc233 balrog
                break;
7009 67867308 bellard
            if (!is_error(ret)) {
7010 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
7011 579a97f7 bellard
                if (!target_grouplist)
7012 579a97f7 bellard
                    goto efault;
7013 a2155fcc balrog
                for(i = 0;i < ret; i++)
7014 0c866a7e Riku Voipio
                    target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
7015 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 2);
7016 67867308 bellard
            }
7017 67867308 bellard
        }
7018 67867308 bellard
        break;
7019 67867308 bellard
    case TARGET_NR_setgroups:
7020 67867308 bellard
        {
7021 67867308 bellard
            int gidsetsize = arg1;
7022 0c866a7e Riku Voipio
            target_id *target_grouplist;
7023 67867308 bellard
            gid_t *grouplist;
7024 67867308 bellard
            int i;
7025 67867308 bellard
7026 67867308 bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7027 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
7028 579a97f7 bellard
            if (!target_grouplist) {
7029 579a97f7 bellard
                ret = -TARGET_EFAULT;
7030 579a97f7 bellard
                goto fail;
7031 579a97f7 bellard
            }
7032 67867308 bellard
            for(i = 0;i < gidsetsize; i++)
7033 0c866a7e Riku Voipio
                grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
7034 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
7035 67867308 bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
7036 67867308 bellard
        }
7037 67867308 bellard
        break;
7038 67867308 bellard
    case TARGET_NR_fchown:
7039 67867308 bellard
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
7040 67867308 bellard
        break;
7041 ccfa72b7 ths
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
7042 ccfa72b7 ths
    case TARGET_NR_fchownat:
7043 579a97f7 bellard
        if (!(p = lock_user_string(arg2))) 
7044 579a97f7 bellard
            goto efault;
7045 579a97f7 bellard
        ret = get_errno(sys_fchownat(arg1, p, low2highuid(arg3), low2highgid(arg4), arg5));
7046 579a97f7 bellard
        unlock_user(p, arg2, 0);
7047 ccfa72b7 ths
        break;
7048 ccfa72b7 ths
#endif
7049 67867308 bellard
#ifdef TARGET_NR_setresuid
7050 67867308 bellard
    case TARGET_NR_setresuid:
7051 5fafdf24 ths
        ret = get_errno(setresuid(low2highuid(arg1),
7052 5fafdf24 ths
                                  low2highuid(arg2),
7053 67867308 bellard
                                  low2highuid(arg3)));
7054 67867308 bellard
        break;
7055 67867308 bellard
#endif
7056 67867308 bellard
#ifdef TARGET_NR_getresuid
7057 67867308 bellard
    case TARGET_NR_getresuid:
7058 67867308 bellard
        {
7059 53a5960a pbrook
            uid_t ruid, euid, suid;
7060 67867308 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7061 67867308 bellard
            if (!is_error(ret)) {
7062 2f619698 bellard
                if (put_user_u16(high2lowuid(ruid), arg1)
7063 2f619698 bellard
                    || put_user_u16(high2lowuid(euid), arg2)
7064 2f619698 bellard
                    || put_user_u16(high2lowuid(suid), arg3))
7065 2f619698 bellard
                    goto efault;
7066 67867308 bellard
            }
7067 67867308 bellard
        }
7068 67867308 bellard
        break;
7069 67867308 bellard
#endif
7070 67867308 bellard
#ifdef TARGET_NR_getresgid
7071 67867308 bellard
    case TARGET_NR_setresgid:
7072 5fafdf24 ths
        ret = get_errno(setresgid(low2highgid(arg1),
7073 5fafdf24 ths
                                  low2highgid(arg2),
7074 67867308 bellard
                                  low2highgid(arg3)));
7075 67867308 bellard
        break;
7076 67867308 bellard
#endif
7077 67867308 bellard
#ifdef TARGET_NR_getresgid
7078 67867308 bellard
    case TARGET_NR_getresgid:
7079 67867308 bellard
        {
7080 53a5960a pbrook
            gid_t rgid, egid, sgid;
7081 67867308 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7082 67867308 bellard
            if (!is_error(ret)) {
7083 2f619698 bellard
                if (put_user_u16(high2lowgid(rgid), arg1)
7084 2f619698 bellard
                    || put_user_u16(high2lowgid(egid), arg2)
7085 2f619698 bellard
                    || put_user_u16(high2lowgid(sgid), arg3))
7086 2f619698 bellard
                    goto efault;
7087 67867308 bellard
            }
7088 67867308 bellard
        }
7089 67867308 bellard
        break;
7090 67867308 bellard
#endif
7091 67867308 bellard
    case TARGET_NR_chown:
7092 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
7093 579a97f7 bellard
            goto efault;
7094 53a5960a pbrook
        ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
7095 53a5960a pbrook
        unlock_user(p, arg1, 0);
7096 67867308 bellard
        break;
7097 67867308 bellard
    case TARGET_NR_setuid:
7098 67867308 bellard
        ret = get_errno(setuid(low2highuid(arg1)));
7099 67867308 bellard
        break;
7100 67867308 bellard
    case TARGET_NR_setgid:
7101 67867308 bellard
        ret = get_errno(setgid(low2highgid(arg1)));
7102 67867308 bellard
        break;
7103 67867308 bellard
    case TARGET_NR_setfsuid:
7104 67867308 bellard
        ret = get_errno(setfsuid(arg1));
7105 67867308 bellard
        break;
7106 67867308 bellard
    case TARGET_NR_setfsgid:
7107 67867308 bellard
        ret = get_errno(setfsgid(arg1));
7108 67867308 bellard
        break;
7109 67867308 bellard
7110 a315a145 bellard
#ifdef TARGET_NR_lchown32
7111 31e31b8a bellard
    case TARGET_NR_lchown32:
7112 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
7113 579a97f7 bellard
            goto efault;
7114 53a5960a pbrook
        ret = get_errno(lchown(p, arg2, arg3));
7115 53a5960a pbrook
        unlock_user(p, arg1, 0);
7116 b03c60f3 bellard
        break;
7117 a315a145 bellard
#endif
7118 a315a145 bellard
#ifdef TARGET_NR_getuid32
7119 31e31b8a bellard
    case TARGET_NR_getuid32:
7120 b03c60f3 bellard
        ret = get_errno(getuid());
7121 b03c60f3 bellard
        break;
7122 a315a145 bellard
#endif
7123 64b4d28c aurel32
7124 64b4d28c aurel32
#if defined(TARGET_NR_getxuid) && defined(TARGET_ALPHA)
7125 64b4d28c aurel32
   /* Alpha specific */
7126 64b4d28c aurel32
    case TARGET_NR_getxuid:
7127 ba0e276d Richard Henderson
         {
7128 ba0e276d Richard Henderson
            uid_t euid;
7129 ba0e276d Richard Henderson
            euid=geteuid();
7130 ba0e276d Richard Henderson
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=euid;
7131 ba0e276d Richard Henderson
         }
7132 64b4d28c aurel32
        ret = get_errno(getuid());
7133 64b4d28c aurel32
        break;
7134 64b4d28c aurel32
#endif
7135 64b4d28c aurel32
#if defined(TARGET_NR_getxgid) && defined(TARGET_ALPHA)
7136 64b4d28c aurel32
   /* Alpha specific */
7137 64b4d28c aurel32
    case TARGET_NR_getxgid:
7138 ba0e276d Richard Henderson
         {
7139 ba0e276d Richard Henderson
            uid_t egid;
7140 ba0e276d Richard Henderson
            egid=getegid();
7141 ba0e276d Richard Henderson
            ((CPUAlphaState *)cpu_env)->ir[IR_A4]=egid;
7142 ba0e276d Richard Henderson
         }
7143 64b4d28c aurel32
        ret = get_errno(getgid());
7144 64b4d28c aurel32
        break;
7145 64b4d28c aurel32
#endif
7146 ba0e276d Richard Henderson
#if defined(TARGET_NR_osf_getsysinfo) && defined(TARGET_ALPHA)
7147 ba0e276d Richard Henderson
    /* Alpha specific */
7148 ba0e276d Richard Henderson
    case TARGET_NR_osf_getsysinfo:
7149 ba0e276d Richard Henderson
        ret = -TARGET_EOPNOTSUPP;
7150 ba0e276d Richard Henderson
        switch (arg1) {
7151 ba0e276d Richard Henderson
          case TARGET_GSI_IEEE_FP_CONTROL:
7152 ba0e276d Richard Henderson
            {
7153 ba0e276d Richard Henderson
                uint64_t swcr, fpcr = cpu_alpha_load_fpcr (cpu_env);
7154 ba0e276d Richard Henderson
7155 ba0e276d Richard Henderson
                /* Copied from linux ieee_fpcr_to_swcr.  */
7156 ba0e276d Richard Henderson
                swcr = (fpcr >> 35) & SWCR_STATUS_MASK;
7157 ba0e276d Richard Henderson
                swcr |= (fpcr >> 36) & SWCR_MAP_DMZ;
7158 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 48) & (SWCR_TRAP_ENABLE_INV
7159 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_DZE
7160 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_OVF);
7161 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 57) & (SWCR_TRAP_ENABLE_UNF
7162 ba0e276d Richard Henderson
                                        | SWCR_TRAP_ENABLE_INE);
7163 ba0e276d Richard Henderson
                swcr |= (fpcr >> 47) & SWCR_MAP_UMZ;
7164 ba0e276d Richard Henderson
                swcr |= (~fpcr >> 41) & SWCR_TRAP_ENABLE_DNO;
7165 ba0e276d Richard Henderson
7166 ba0e276d Richard Henderson
                if (put_user_u64 (swcr, arg2))
7167 ba0e276d Richard Henderson
                        goto efault;
7168 ba0e276d Richard Henderson
                ret = 0;
7169 ba0e276d Richard Henderson
            }
7170 ba0e276d Richard Henderson
            break;
7171 ba0e276d Richard Henderson
7172 ba0e276d Richard Henderson
          /* case GSI_IEEE_STATE_AT_SIGNAL:
7173 ba0e276d Richard Henderson
             -- Not implemented in linux kernel.
7174 ba0e276d Richard Henderson
             case GSI_UACPROC:
7175 ba0e276d Richard Henderson
             -- Retrieves current unaligned access state; not much used.
7176 ba0e276d Richard Henderson
             case GSI_PROC_TYPE:
7177 ba0e276d Richard Henderson
             -- Retrieves implver information; surely not used.
7178 ba0e276d Richard Henderson
             case GSI_GET_HWRPB:
7179 ba0e276d Richard Henderson
             -- Grabs a copy of the HWRPB; surely not used.
7180 ba0e276d Richard Henderson
          */
7181 ba0e276d Richard Henderson
        }
7182 ba0e276d Richard Henderson
        break;
7183 ba0e276d Richard Henderson
#endif
7184 ba0e276d Richard Henderson
#if defined(TARGET_NR_osf_setsysinfo) && defined(TARGET_ALPHA)
7185 ba0e276d Richard Henderson
    /* Alpha specific */
7186 ba0e276d Richard Henderson
    case TARGET_NR_osf_setsysinfo:
7187 ba0e276d Richard Henderson
        ret = -TARGET_EOPNOTSUPP;
7188 ba0e276d Richard Henderson
        switch (arg1) {
7189 ba0e276d Richard Henderson
          case TARGET_SSI_IEEE_FP_CONTROL:
7190 ba0e276d Richard Henderson
          case TARGET_SSI_IEEE_RAISE_EXCEPTION:
7191 ba0e276d Richard Henderson
            {
7192 ba0e276d Richard Henderson
                uint64_t swcr, fpcr, orig_fpcr;
7193 ba0e276d Richard Henderson
7194 ba0e276d Richard Henderson
                if (get_user_u64 (swcr, arg2))
7195 ba0e276d Richard Henderson
                    goto efault;
7196 ba0e276d Richard Henderson
                orig_fpcr = cpu_alpha_load_fpcr (cpu_env);
7197 ba0e276d Richard Henderson
                fpcr = orig_fpcr & FPCR_DYN_MASK;
7198 ba0e276d Richard Henderson
7199 ba0e276d Richard Henderson
                /* Copied from linux ieee_swcr_to_fpcr.  */
7200 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_STATUS_MASK) << 35;
7201 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_MAP_DMZ) << 36;
7202 ba0e276d Richard Henderson
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_INV
7203 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_DZE
7204 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_OVF)) << 48;
7205 ba0e276d Richard Henderson
                fpcr |= (~swcr & (SWCR_TRAP_ENABLE_UNF
7206 ba0e276d Richard Henderson
                                  | SWCR_TRAP_ENABLE_INE)) << 57;
7207 ba0e276d Richard Henderson
                fpcr |= (swcr & SWCR_MAP_UMZ ? FPCR_UNDZ | FPCR_UNFD : 0);
7208 ba0e276d Richard Henderson
                fpcr |= (~swcr & SWCR_TRAP_ENABLE_DNO) << 41;
7209 ba0e276d Richard Henderson
7210 ba0e276d Richard Henderson
                cpu_alpha_store_fpcr (cpu_env, fpcr);
7211 ba0e276d Richard Henderson
                ret = 0;
7212 ba0e276d Richard Henderson
7213 ba0e276d Richard Henderson
                if (arg1 == TARGET_SSI_IEEE_RAISE_EXCEPTION) {
7214 ba0e276d Richard Henderson
                    /* Old exceptions are not signaled.  */
7215 ba0e276d Richard Henderson
                    fpcr &= ~(orig_fpcr & FPCR_STATUS_MASK);
7216 ba0e276d Richard Henderson
7217 ba0e276d Richard Henderson
                    /* If any exceptions set by this call, and are unmasked,
7218 ba0e276d Richard Henderson
                       send a signal.  */
7219 ba0e276d Richard Henderson
                    /* ??? FIXME */
7220 ba0e276d Richard Henderson
                }
7221 ba0e276d Richard Henderson
            }
7222 ba0e276d Richard Henderson
            break;
7223 ba0e276d Richard Henderson
7224 ba0e276d Richard Henderson
          /* case SSI_NVPAIRS:
7225 ba0e276d Richard Henderson
             -- Used with SSIN_UACPROC to enable unaligned accesses.
7226 ba0e276d Richard Henderson
             case SSI_IEEE_STATE_AT_SIGNAL:
7227 ba0e276d Richard Henderson
             case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:
7228 ba0e276d Richard Henderson
             -- Not implemented in linux kernel
7229 ba0e276d Richard Henderson
          */
7230 ba0e276d Richard Henderson
        }
7231 ba0e276d Richard Henderson
        break;
7232 ba0e276d Richard Henderson
#endif
7233 ba0e276d Richard Henderson
#ifdef TARGET_NR_osf_sigprocmask
7234 ba0e276d Richard Henderson
    /* Alpha specific.  */
7235 ba0e276d Richard Henderson
    case TARGET_NR_osf_sigprocmask:
7236 ba0e276d Richard Henderson
        {
7237 ba0e276d Richard Henderson
            abi_ulong mask;
7238 bc088ba1 Juan Quintela
            int how;
7239 ba0e276d Richard Henderson
            sigset_t set, oldset;
7240 ba0e276d Richard Henderson
7241 ba0e276d Richard Henderson
            switch(arg1) {
7242 ba0e276d Richard Henderson
            case TARGET_SIG_BLOCK:
7243 ba0e276d Richard Henderson
                how = SIG_BLOCK;
7244 ba0e276d Richard Henderson
                break;
7245 ba0e276d Richard Henderson
            case TARGET_SIG_UNBLOCK:
7246 ba0e276d Richard Henderson
                how = SIG_UNBLOCK;
7247 ba0e276d Richard Henderson
                break;
7248 ba0e276d Richard Henderson
            case TARGET_SIG_SETMASK:
7249 ba0e276d Richard Henderson
                how = SIG_SETMASK;
7250 ba0e276d Richard Henderson
                break;
7251 ba0e276d Richard Henderson
            default:
7252 ba0e276d Richard Henderson
                ret = -TARGET_EINVAL;
7253 ba0e276d Richard Henderson
                goto fail;
7254 ba0e276d Richard Henderson
            }
7255 ba0e276d Richard Henderson
            mask = arg2;
7256 ba0e276d Richard Henderson
            target_to_host_old_sigset(&set, &mask);
7257 bc088ba1 Juan Quintela
            sigprocmask(how, &set, &oldset);
7258 ba0e276d Richard Henderson
            host_to_target_old_sigset(&mask, &oldset);
7259 ba0e276d Richard Henderson
            ret = mask;
7260 ba0e276d Richard Henderson
        }
7261 ba0e276d Richard Henderson
        break;
7262 ba0e276d Richard Henderson
#endif
7263 64b4d28c aurel32
7264 a315a145 bellard
#ifdef TARGET_NR_getgid32
7265 31e31b8a bellard
    case TARGET_NR_getgid32:
7266 b03c60f3 bellard
        ret = get_errno(getgid());
7267 b03c60f3 bellard
        break;
7268 a315a145 bellard
#endif
7269 a315a145 bellard
#ifdef TARGET_NR_geteuid32
7270 31e31b8a bellard
    case TARGET_NR_geteuid32:
7271 b03c60f3 bellard
        ret = get_errno(geteuid());
7272 b03c60f3 bellard
        break;
7273 a315a145 bellard
#endif
7274 a315a145 bellard
#ifdef TARGET_NR_getegid32
7275 31e31b8a bellard
    case TARGET_NR_getegid32:
7276 b03c60f3 bellard
        ret = get_errno(getegid());
7277 b03c60f3 bellard
        break;
7278 a315a145 bellard
#endif
7279 a315a145 bellard
#ifdef TARGET_NR_setreuid32
7280 31e31b8a bellard
    case TARGET_NR_setreuid32:
7281 b03c60f3 bellard
        ret = get_errno(setreuid(arg1, arg2));
7282 b03c60f3 bellard
        break;
7283 a315a145 bellard
#endif
7284 a315a145 bellard
#ifdef TARGET_NR_setregid32
7285 31e31b8a bellard
    case TARGET_NR_setregid32:
7286 b03c60f3 bellard
        ret = get_errno(setregid(arg1, arg2));
7287 b03c60f3 bellard
        break;
7288 a315a145 bellard
#endif
7289 a315a145 bellard
#ifdef TARGET_NR_getgroups32
7290 31e31b8a bellard
    case TARGET_NR_getgroups32:
7291 99c475ab bellard
        {
7292 99c475ab bellard
            int gidsetsize = arg1;
7293 53a5960a pbrook
            uint32_t *target_grouplist;
7294 99c475ab bellard
            gid_t *grouplist;
7295 99c475ab bellard
            int i;
7296 99c475ab bellard
7297 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7298 99c475ab bellard
            ret = get_errno(getgroups(gidsetsize, grouplist));
7299 cb3bc233 balrog
            if (gidsetsize == 0)
7300 cb3bc233 balrog
                break;
7301 99c475ab bellard
            if (!is_error(ret)) {
7302 579a97f7 bellard
                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 4, 0);
7303 579a97f7 bellard
                if (!target_grouplist) {
7304 579a97f7 bellard
                    ret = -TARGET_EFAULT;
7305 579a97f7 bellard
                    goto fail;
7306 579a97f7 bellard
                }
7307 a2155fcc balrog
                for(i = 0;i < ret; i++)
7308 53a5960a pbrook
                    target_grouplist[i] = tswap32(grouplist[i]);
7309 53a5960a pbrook
                unlock_user(target_grouplist, arg2, gidsetsize * 4);
7310 99c475ab bellard
            }
7311 99c475ab bellard
        }
7312 99c475ab bellard
        break;
7313 a315a145 bellard
#endif
7314 a315a145 bellard
#ifdef TARGET_NR_setgroups32
7315 31e31b8a bellard
    case TARGET_NR_setgroups32:
7316 99c475ab bellard
        {
7317 99c475ab bellard
            int gidsetsize = arg1;
7318 53a5960a pbrook
            uint32_t *target_grouplist;
7319 99c475ab bellard
            gid_t *grouplist;
7320 99c475ab bellard
            int i;
7321 3b46e624 ths
7322 99c475ab bellard
            grouplist = alloca(gidsetsize * sizeof(gid_t));
7323 579a97f7 bellard
            target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 4, 1);
7324 579a97f7 bellard
            if (!target_grouplist) {
7325 579a97f7 bellard
                ret = -TARGET_EFAULT;
7326 579a97f7 bellard
                goto fail;
7327 579a97f7 bellard
            }
7328 99c475ab bellard
            for(i = 0;i < gidsetsize; i++)
7329 53a5960a pbrook
                grouplist[i] = tswap32(target_grouplist[i]);
7330 53a5960a pbrook
            unlock_user(target_grouplist, arg2, 0);
7331 99c475ab bellard
            ret = get_errno(setgroups(gidsetsize, grouplist));
7332 99c475ab bellard
        }
7333 99c475ab bellard
        break;
7334 a315a145 bellard
#endif
7335 a315a145 bellard
#ifdef TARGET_NR_fchown32
7336 31e31b8a bellard
    case TARGET_NR_fchown32:
7337 b03c60f3 bellard
        ret = get_errno(fchown(arg1, arg2, arg3));
7338 b03c60f3 bellard
        break;
7339 a315a145 bellard
#endif
7340 a315a145 bellard
#ifdef TARGET_NR_setresuid32
7341 31e31b8a bellard
    case TARGET_NR_setresuid32:
7342 b03c60f3 bellard
        ret = get_errno(setresuid(arg1, arg2, arg3));
7343 b03c60f3 bellard
        break;
7344 a315a145 bellard
#endif
7345 a315a145 bellard
#ifdef TARGET_NR_getresuid32
7346 31e31b8a bellard
    case TARGET_NR_getresuid32:
7347 b03c60f3 bellard
        {
7348 53a5960a pbrook
            uid_t ruid, euid, suid;
7349 b03c60f3 bellard
            ret = get_errno(getresuid(&ruid, &euid, &suid));
7350 b03c60f3 bellard
            if (!is_error(ret)) {
7351 2f619698 bellard
                if (put_user_u32(ruid, arg1)
7352 2f619698 bellard
                    || put_user_u32(euid, arg2)
7353 2f619698 bellard
                    || put_user_u32(suid, arg3))
7354 2f619698 bellard
                    goto efault;
7355 b03c60f3 bellard
            }
7356 b03c60f3 bellard
        }
7357 b03c60f3 bellard
        break;
7358 a315a145 bellard
#endif
7359 a315a145 bellard
#ifdef TARGET_NR_setresgid32
7360 31e31b8a bellard
    case TARGET_NR_setresgid32:
7361 b03c60f3 bellard
        ret = get_errno(setresgid(arg1, arg2, arg3));
7362 b03c60f3 bellard
        break;
7363 a315a145 bellard
#endif
7364 a315a145 bellard
#ifdef TARGET_NR_getresgid32
7365 31e31b8a bellard
    case TARGET_NR_getresgid32:
7366 b03c60f3 bellard
        {
7367 53a5960a pbrook
            gid_t rgid, egid, sgid;
7368 b03c60f3 bellard
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
7369 b03c60f3 bellard
            if (!is_error(ret)) {
7370 2f619698 bellard
                if (put_user_u32(rgid, arg1)
7371 2f619698 bellard
                    || put_user_u32(egid, arg2)
7372 2f619698 bellard
                    || put_user_u32(sgid, arg3))
7373 2f619698 bellard
                    goto efault;
7374 b03c60f3 bellard
            }
7375 b03c60f3 bellard
        }
7376 b03c60f3 bellard
        break;
7377 a315a145 bellard
#endif
7378 a315a145 bellard
#ifdef TARGET_NR_chown32
7379 31e31b8a bellard
    case TARGET_NR_chown32:
7380 579a97f7 bellard
        if (!(p = lock_user_string(arg1)))
7381 579a97f7 bellard
            goto efault;
7382 53a5960a pbrook
        ret = get_errno(chown(p, arg2, arg3));
7383 53a5960a pbrook
        unlock_user(p, arg1, 0);
7384 b03c60f3 bellard
        break;
7385 a315a145 bellard
#endif
7386 a315a145 bellard
#ifdef TARGET_NR_setuid32
7387 31e31b8a bellard
    case TARGET_NR_setuid32:
7388 b03c60f3 bellard
        ret = get_errno(setuid(arg1));
7389 b03c60f3 bellard
        break;
7390 a315a145 bellard
#endif
7391 a315a145 bellard
#ifdef TARGET_NR_setgid32
7392 31e31b8a bellard
    case TARGET_NR_setgid32:
7393 b03c60f3 bellard
        ret = get_errno(setgid(arg1));
7394 b03c60f3 bellard
        break;
7395 a315a145 bellard
#endif
7396 a315a145 bellard
#ifdef TARGET_NR_setfsuid32
7397 31e31b8a bellard
    case TARGET_NR_setfsuid32:
7398 b03c60f3 bellard
        ret = get_errno(setfsuid(arg1));
7399 b03c60f3 bellard
        break;
7400 a315a145 bellard
#endif
7401 a315a145 bellard
#ifdef TARGET_NR_setfsgid32
7402 31e31b8a bellard
    case TARGET_NR_setfsgid32:
7403 b03c60f3 bellard
        ret = get_errno(setfsgid(arg1));
7404 b03c60f3 bellard
        break;
7405 a315a145 bellard
#endif
7406 67867308 bellard
7407 31e31b8a bellard
    case TARGET_NR_pivot_root:
7408 b03c60f3 bellard
        goto unimplemented;
7409 ffa65c3b bellard
#ifdef TARGET_NR_mincore
7410 31e31b8a bellard
    case TARGET_NR_mincore:
7411 04bb9ace aurel32
        {
7412 04bb9ace aurel32
            void *a;
7413 04bb9ace aurel32
            ret = -TARGET_EFAULT;
7414 04bb9ace aurel32
            if (!(a = lock_user(VERIFY_READ, arg1,arg2, 0)))
7415 04bb9ace aurel32
                goto efault;
7416 04bb9ace aurel32
            if (!(p = lock_user_string(arg3)))
7417 04bb9ace aurel32
                goto mincore_fail;
7418 04bb9ace aurel32
            ret = get_errno(mincore(a, arg2, p));
7419 04bb9ace aurel32
            unlock_user(p, arg3, ret);
7420 04bb9ace aurel32
            mincore_fail:
7421 04bb9ace aurel32
            unlock_user(a, arg1, 0);
7422 04bb9ace aurel32
        }
7423 04bb9ace aurel32
        break;
7424 ffa65c3b bellard
#endif
7425 408321b6 aurel32
#ifdef TARGET_NR_arm_fadvise64_64
7426 408321b6 aurel32
    case TARGET_NR_arm_fadvise64_64:
7427 408321b6 aurel32
        {
7428 408321b6 aurel32
                /*
7429 408321b6 aurel32
                 * arm_fadvise64_64 looks like fadvise64_64 but
7430 408321b6 aurel32
                 * with different argument order
7431 408321b6 aurel32
                 */
7432 408321b6 aurel32
                abi_long temp;
7433 408321b6 aurel32
                temp = arg3;
7434 408321b6 aurel32
                arg3 = arg4;
7435 408321b6 aurel32
                arg4 = temp;
7436 408321b6 aurel32
        }
7437 408321b6 aurel32
#endif
7438 e72d2cc7 Ulrich Hecht
#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
7439 408321b6 aurel32
#ifdef TARGET_NR_fadvise64_64
7440 408321b6 aurel32
    case TARGET_NR_fadvise64_64:
7441 408321b6 aurel32
#endif
7442 e72d2cc7 Ulrich Hecht
#ifdef TARGET_NR_fadvise64
7443 e72d2cc7 Ulrich Hecht
    case TARGET_NR_fadvise64:
7444 e72d2cc7 Ulrich Hecht
#endif
7445 e72d2cc7 Ulrich Hecht
#ifdef TARGET_S390X
7446 e72d2cc7 Ulrich Hecht
        switch (arg4) {
7447 e72d2cc7 Ulrich Hecht
        case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
7448 e72d2cc7 Ulrich Hecht
        case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
7449 e72d2cc7 Ulrich Hecht
        case 6: arg4 = POSIX_FADV_DONTNEED; break;
7450 e72d2cc7 Ulrich Hecht
        case 7: arg4 = POSIX_FADV_NOREUSE; break;
7451 e72d2cc7 Ulrich Hecht
        default: break;
7452 e72d2cc7 Ulrich Hecht
        }
7453 e72d2cc7 Ulrich Hecht
#endif
7454 e72d2cc7 Ulrich Hecht
        ret = -posix_fadvise(arg1, arg2, arg3, arg4);
7455 408321b6 aurel32
        break;
7456 408321b6 aurel32
#endif
7457 ffa65c3b bellard
#ifdef TARGET_NR_madvise
7458 31e31b8a bellard
    case TARGET_NR_madvise:
7459 24836689 pbrook
        /* A straight passthrough may not be safe because qemu sometimes
7460 24836689 pbrook
           turns private flie-backed mappings into anonymous mappings.
7461 24836689 pbrook
           This will break MADV_DONTNEED.
7462 24836689 pbrook
           This is a hint, so ignoring and returning success is ok.  */
7463 24836689 pbrook
        ret = get_errno(0);
7464 24836689 pbrook
        break;
7465 ffa65c3b bellard
#endif
7466 992f48a0 blueswir1
#if TARGET_ABI_BITS == 32
7467 31e31b8a bellard
    case TARGET_NR_fcntl64:
7468 77e4672d bellard
    {
7469 b1e341eb ths
        int cmd;
7470 77e4672d bellard
        struct flock64 fl;
7471 53a5960a pbrook
        struct target_flock64 *target_fl;
7472 ce4defa0 pbrook
#ifdef TARGET_ARM
7473 53a5960a pbrook
        struct target_eabi_flock64 *target_efl;
7474 ce4defa0 pbrook
#endif
7475 77e4672d bellard
7476 5f106811 Arnaud Patard (Rtp)
        cmd = target_to_host_fcntl_cmd(arg2);
7477 5f106811 Arnaud Patard (Rtp)
        if (cmd == -TARGET_EINVAL)
7478 5f106811 Arnaud Patard (Rtp)
                return cmd;
7479 b1e341eb ths
7480 60cd49d5 bellard
        switch(arg2) {
7481 b1e341eb ths
        case TARGET_F_GETLK64:
7482 5813427b ths
#ifdef TARGET_ARM
7483 5813427b ths
            if (((CPUARMState *)cpu_env)->eabi) {
7484 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7485 9ee1fa2c bellard
                    goto efault;
7486 5813427b ths
                fl.l_type = tswap16(target_efl->l_type);
7487 5813427b ths
                fl.l_whence = tswap16(target_efl->l_whence);
7488 5813427b ths
                fl.l_start = tswap64(target_efl->l_start);
7489 5813427b ths
                fl.l_len = tswap64(target_efl->l_len);
7490 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_efl->l_pid);
7491 5813427b ths
                unlock_user_struct(target_efl, arg3, 0);
7492 5813427b ths
            } else
7493 5813427b ths
#endif
7494 5813427b ths
            {
7495 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7496 9ee1fa2c bellard
                    goto efault;
7497 5813427b ths
                fl.l_type = tswap16(target_fl->l_type);
7498 5813427b ths
                fl.l_whence = tswap16(target_fl->l_whence);
7499 5813427b ths
                fl.l_start = tswap64(target_fl->l_start);
7500 5813427b ths
                fl.l_len = tswap64(target_fl->l_len);
7501 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_fl->l_pid);
7502 5813427b ths
                unlock_user_struct(target_fl, arg3, 0);
7503 5813427b ths
            }
7504 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
7505 77e4672d bellard
            if (ret == 0) {
7506 ce4defa0 pbrook
#ifdef TARGET_ARM
7507 ce4defa0 pbrook
                if (((CPUARMState *)cpu_env)->eabi) {
7508 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_efl, arg3, 0)) 
7509 9ee1fa2c bellard
                        goto efault;
7510 ce4defa0 pbrook
                    target_efl->l_type = tswap16(fl.l_type);
7511 ce4defa0 pbrook
                    target_efl->l_whence = tswap16(fl.l_whence);
7512 ce4defa0 pbrook
                    target_efl->l_start = tswap64(fl.l_start);
7513 ce4defa0 pbrook
                    target_efl->l_len = tswap64(fl.l_len);
7514 7e22e546 Ulrich Hecht
                    target_efl->l_pid = tswap32(fl.l_pid);
7515 53a5960a pbrook
                    unlock_user_struct(target_efl, arg3, 1);
7516 ce4defa0 pbrook
                } else
7517 ce4defa0 pbrook
#endif
7518 ce4defa0 pbrook
                {
7519 9ee1fa2c bellard
                    if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) 
7520 9ee1fa2c bellard
                        goto efault;
7521 ce4defa0 pbrook
                    target_fl->l_type = tswap16(fl.l_type);
7522 ce4defa0 pbrook
                    target_fl->l_whence = tswap16(fl.l_whence);
7523 ce4defa0 pbrook
                    target_fl->l_start = tswap64(fl.l_start);
7524 ce4defa0 pbrook
                    target_fl->l_len = tswap64(fl.l_len);
7525 7e22e546 Ulrich Hecht
                    target_fl->l_pid = tswap32(fl.l_pid);
7526 53a5960a pbrook
                    unlock_user_struct(target_fl, arg3, 1);
7527 ce4defa0 pbrook
                }
7528 77e4672d bellard
            }
7529 77e4672d bellard
            break;
7530 77e4672d bellard
7531 b1e341eb ths
        case TARGET_F_SETLK64:
7532 b1e341eb ths
        case TARGET_F_SETLKW64:
7533 ce4defa0 pbrook
#ifdef TARGET_ARM
7534 ce4defa0 pbrook
            if (((CPUARMState *)cpu_env)->eabi) {
7535 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_efl, arg3, 1)) 
7536 9ee1fa2c bellard
                    goto efault;
7537 ce4defa0 pbrook
                fl.l_type = tswap16(target_efl->l_type);
7538 ce4defa0 pbrook
                fl.l_whence = tswap16(target_efl->l_whence);
7539 ce4defa0 pbrook
                fl.l_start = tswap64(target_efl->l_start);
7540 ce4defa0 pbrook
                fl.l_len = tswap64(target_efl->l_len);
7541 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_efl->l_pid);
7542 53a5960a pbrook
                unlock_user_struct(target_efl, arg3, 0);
7543 ce4defa0 pbrook
            } else
7544 ce4defa0 pbrook
#endif
7545 ce4defa0 pbrook
            {
7546 9ee1fa2c bellard
                if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) 
7547 9ee1fa2c bellard
                    goto efault;
7548 ce4defa0 pbrook
                fl.l_type = tswap16(target_fl->l_type);
7549 ce4defa0 pbrook
                fl.l_whence = tswap16(target_fl->l_whence);
7550 ce4defa0 pbrook
                fl.l_start = tswap64(target_fl->l_start);
7551 ce4defa0 pbrook
                fl.l_len = tswap64(target_fl->l_len);
7552 7e22e546 Ulrich Hecht
                fl.l_pid = tswap32(target_fl->l_pid);
7553 53a5960a pbrook
                unlock_user_struct(target_fl, arg3, 0);
7554 ce4defa0 pbrook
            }
7555 b1e341eb ths
            ret = get_errno(fcntl(arg1, cmd, &fl));
7556 77e4672d bellard
            break;
7557 60cd49d5 bellard
        default:
7558 5f106811 Arnaud Patard (Rtp)
            ret = do_fcntl(arg1, arg2, arg3);
7559 60cd49d5 bellard
            break;
7560 60cd49d5 bellard
        }
7561 77e4672d bellard
        break;
7562 77e4672d bellard
    }
7563 60cd49d5 bellard
#endif
7564 7d600c80 ths
#ifdef TARGET_NR_cacheflush
7565 7d600c80 ths
    case TARGET_NR_cacheflush:
7566 7d600c80 ths
        /* self-modifying code is handled automatically, so nothing needed */
7567 7d600c80 ths
        ret = 0;
7568 7d600c80 ths
        break;
7569 7d600c80 ths
#endif
7570 ebc05488 bellard
#ifdef TARGET_NR_security
7571 31e31b8a bellard
    case TARGET_NR_security:
7572 31e31b8a bellard
        goto unimplemented;
7573 ebc05488 bellard
#endif
7574 c573ff67 bellard
#ifdef TARGET_NR_getpagesize
7575 c573ff67 bellard
    case TARGET_NR_getpagesize:
7576 c573ff67 bellard
        ret = TARGET_PAGE_SIZE;
7577 c573ff67 bellard
        break;
7578 c573ff67 bellard
#endif
7579 31e31b8a bellard
    case TARGET_NR_gettid:
7580 31e31b8a bellard
        ret = get_errno(gettid());
7581 31e31b8a bellard
        break;
7582 e5febef5 ths
#ifdef TARGET_NR_readahead
7583 31e31b8a bellard
    case TARGET_NR_readahead:
7584 2054ac9b aurel32
#if TARGET_ABI_BITS == 32
7585 2054ac9b aurel32
#ifdef TARGET_ARM
7586 2054ac9b aurel32
        if (((CPUARMState *)cpu_env)->eabi)
7587 2054ac9b aurel32
        {
7588 2054ac9b aurel32
            arg2 = arg3;
7589 2054ac9b aurel32
            arg3 = arg4;
7590 2054ac9b aurel32
            arg4 = arg5;
7591 2054ac9b aurel32
        }
7592 2054ac9b aurel32
#endif
7593 2054ac9b aurel32
        ret = get_errno(readahead(arg1, ((off64_t)arg3 << 32) | arg2, arg4));
7594 2054ac9b aurel32
#else
7595 2054ac9b aurel32
        ret = get_errno(readahead(arg1, arg2, arg3));
7596 2054ac9b aurel32
#endif
7597 2054ac9b aurel32
        break;
7598 e5febef5 ths
#endif
7599 ebc05488 bellard
#ifdef TARGET_NR_setxattr
7600 31e31b8a bellard
    case TARGET_NR_setxattr:
7601 31e31b8a bellard
    case TARGET_NR_lsetxattr:
7602 31e31b8a bellard
    case TARGET_NR_fsetxattr:
7603 31e31b8a bellard
    case TARGET_NR_getxattr:
7604 31e31b8a bellard
    case TARGET_NR_lgetxattr:
7605 31e31b8a bellard
    case TARGET_NR_fgetxattr:
7606 31e31b8a bellard
    case TARGET_NR_listxattr:
7607 31e31b8a bellard
    case TARGET_NR_llistxattr:
7608 31e31b8a bellard
    case TARGET_NR_flistxattr:
7609 31e31b8a bellard
    case TARGET_NR_removexattr:
7610 31e31b8a bellard
    case TARGET_NR_lremovexattr:
7611 31e31b8a bellard
    case TARGET_NR_fremovexattr:
7612 6f932f91 Arnaud Patard
        ret = -TARGET_EOPNOTSUPP;
7613 6f932f91 Arnaud Patard
        break;
7614 ebc05488 bellard
#endif
7615 ebc05488 bellard
#ifdef TARGET_NR_set_thread_area
7616 5cd4393b bellard
    case TARGET_NR_set_thread_area:
7617 8d18e893 bellard
#if defined(TARGET_MIPS)
7618 6f5b89a0 ths
      ((CPUMIPSState *) cpu_env)->tls_value = arg1;
7619 6f5b89a0 ths
      ret = 0;
7620 6f5b89a0 ths
      break;
7621 ef96779b edgar_igl
#elif defined(TARGET_CRIS)
7622 ef96779b edgar_igl
      if (arg1 & 0xff)
7623 ef96779b edgar_igl
          ret = -TARGET_EINVAL;
7624 ef96779b edgar_igl
      else {
7625 ef96779b edgar_igl
          ((CPUCRISState *) cpu_env)->pregs[PR_PID] = arg1;
7626 ef96779b edgar_igl
          ret = 0;
7627 ef96779b edgar_igl
      }
7628 ef96779b edgar_igl
      break;
7629 8d18e893 bellard
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
7630 8d18e893 bellard
      ret = do_set_thread_area(cpu_env, arg1);
7631 8d18e893 bellard
      break;
7632 6f5b89a0 ths
#else
7633 6f5b89a0 ths
      goto unimplemented_nowarn;
7634 6f5b89a0 ths
#endif
7635 6f5b89a0 ths
#endif
7636 6f5b89a0 ths
#ifdef TARGET_NR_get_thread_area
7637 5cd4393b bellard
    case TARGET_NR_get_thread_area:
7638 8d18e893 bellard
#if defined(TARGET_I386) && defined(TARGET_ABI32)
7639 8d18e893 bellard
        ret = do_get_thread_area(cpu_env, arg1);
7640 8d18e893 bellard
#else
7641 5cd4393b bellard
        goto unimplemented_nowarn;
7642 ebc05488 bellard
#endif
7643 8d18e893 bellard
#endif
7644 48dc41eb bellard
#ifdef TARGET_NR_getdomainname
7645 48dc41eb bellard
    case TARGET_NR_getdomainname:
7646 48dc41eb bellard
        goto unimplemented_nowarn;
7647 48dc41eb bellard
#endif
7648 6f5b89a0 ths
7649 b5906f95 ths
#ifdef TARGET_NR_clock_gettime
7650 b5906f95 ths
    case TARGET_NR_clock_gettime:
7651 b5906f95 ths
    {
7652 b5906f95 ths
        struct timespec ts;
7653 b5906f95 ths
        ret = get_errno(clock_gettime(arg1, &ts));
7654 b5906f95 ths
        if (!is_error(ret)) {
7655 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
7656 b5906f95 ths
        }
7657 b5906f95 ths
        break;
7658 b5906f95 ths
    }
7659 b5906f95 ths
#endif
7660 b5906f95 ths
#ifdef TARGET_NR_clock_getres
7661 b5906f95 ths
    case TARGET_NR_clock_getres:
7662 b5906f95 ths
    {
7663 b5906f95 ths
        struct timespec ts;
7664 b5906f95 ths
        ret = get_errno(clock_getres(arg1, &ts));
7665 b5906f95 ths
        if (!is_error(ret)) {
7666 b5906f95 ths
            host_to_target_timespec(arg2, &ts);
7667 b5906f95 ths
        }
7668 b5906f95 ths
        break;
7669 b5906f95 ths
    }
7670 b5906f95 ths
#endif
7671 63d7651b pbrook
#ifdef TARGET_NR_clock_nanosleep
7672 63d7651b pbrook
    case TARGET_NR_clock_nanosleep:
7673 63d7651b pbrook
    {
7674 63d7651b pbrook
        struct timespec ts;
7675 63d7651b pbrook
        target_to_host_timespec(&ts, arg3);
7676 63d7651b pbrook
        ret = get_errno(clock_nanosleep(arg1, arg2, &ts, arg4 ? &ts : NULL));
7677 63d7651b pbrook
        if (arg4)
7678 63d7651b pbrook
            host_to_target_timespec(arg4, &ts);
7679 63d7651b pbrook
        break;
7680 63d7651b pbrook
    }
7681 63d7651b pbrook
#endif
7682 b5906f95 ths
7683 6f5b89a0 ths
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
7684 6f5b89a0 ths
    case TARGET_NR_set_tid_address:
7685 579a97f7 bellard
        ret = get_errno(set_tid_address((int *)g2h(arg1)));
7686 579a97f7 bellard
        break;
7687 6f5b89a0 ths
#endif
7688 6f5b89a0 ths
7689 3ae43202 ths
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
7690 4cae1d16 ths
    case TARGET_NR_tkill:
7691 4cb05961 pbrook
        ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
7692 4cae1d16 ths
        break;
7693 4cae1d16 ths
#endif
7694 4cae1d16 ths
7695 3ae43202 ths
#if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
7696 71455574 ths
    case TARGET_NR_tgkill:
7697 4cb05961 pbrook
        ret = get_errno(sys_tgkill((int)arg1, (int)arg2,
7698 4cb05961 pbrook
                        target_to_host_signal(arg3)));
7699 71455574 ths
        break;
7700 71455574 ths
#endif
7701 71455574 ths
7702 4f2b1fe8 ths
#ifdef TARGET_NR_set_robust_list
7703 4f2b1fe8 ths
    case TARGET_NR_set_robust_list:
7704 4f2b1fe8 ths
        goto unimplemented_nowarn;
7705 4f2b1fe8 ths
#endif
7706 4f2b1fe8 ths
7707 9007f0ef ths
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
7708 9007f0ef ths
    case TARGET_NR_utimensat:
7709 9007f0ef ths
        {
7710 ebc996f3 Riku Voipio
            struct timespec *tsp, ts[2];
7711 ebc996f3 Riku Voipio
            if (!arg3) {
7712 ebc996f3 Riku Voipio
                tsp = NULL;
7713 ebc996f3 Riku Voipio
            } else {
7714 ebc996f3 Riku Voipio
                target_to_host_timespec(ts, arg3);
7715 ebc996f3 Riku Voipio
                target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
7716 ebc996f3 Riku Voipio
                tsp = ts;
7717 ebc996f3 Riku Voipio
            }
7718 9007f0ef ths
            if (!arg2)
7719 ebc996f3 Riku Voipio
                ret = get_errno(sys_utimensat(arg1, NULL, tsp, arg4));
7720 9007f0ef ths
            else {
7721 579a97f7 bellard
                if (!(p = lock_user_string(arg2))) {
7722 0da46a6e ths
                    ret = -TARGET_EFAULT;
7723 579a97f7 bellard
                    goto fail;
7724 579a97f7 bellard
                }
7725 ebc996f3 Riku Voipio
                ret = get_errno(sys_utimensat(arg1, path(p), tsp, arg4));
7726 579a97f7 bellard
                unlock_user(p, arg2, 0);
7727 9007f0ef ths
            }
7728 9007f0ef ths
        }
7729 9007f0ef ths
        break;
7730 9007f0ef ths
#endif
7731 2f7bb878 Juan Quintela
#if defined(CONFIG_USE_NPTL)
7732 bd0c5661 pbrook
    case TARGET_NR_futex:
7733 bd0c5661 pbrook
        ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
7734 bd0c5661 pbrook
        break;
7735 bd0c5661 pbrook
#endif
7736 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
7737 39b59763 aurel32
    case TARGET_NR_inotify_init:
7738 39b59763 aurel32
        ret = get_errno(sys_inotify_init());
7739 39b59763 aurel32
        break;
7740 39b59763 aurel32
#endif
7741 a1606b0b Stefan Weil
#ifdef CONFIG_INOTIFY1
7742 c05c7a73 Riku Voipio
#if defined(TARGET_NR_inotify_init1) && defined(__NR_inotify_init1)
7743 c05c7a73 Riku Voipio
    case TARGET_NR_inotify_init1:
7744 c05c7a73 Riku Voipio
        ret = get_errno(sys_inotify_init1(arg1));
7745 c05c7a73 Riku Voipio
        break;
7746 c05c7a73 Riku Voipio
#endif
7747 a1606b0b Stefan Weil
#endif
7748 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_add_watch) && defined(__NR_inotify_add_watch)
7749 39b59763 aurel32
    case TARGET_NR_inotify_add_watch:
7750 39b59763 aurel32
        p = lock_user_string(arg2);
7751 39b59763 aurel32
        ret = get_errno(sys_inotify_add_watch(arg1, path(p), arg3));
7752 39b59763 aurel32
        unlock_user(p, arg2, 0);
7753 39b59763 aurel32
        break;
7754 39b59763 aurel32
#endif
7755 dbfe4c36 aurel32
#if defined(TARGET_NR_inotify_rm_watch) && defined(__NR_inotify_rm_watch)
7756 39b59763 aurel32
    case TARGET_NR_inotify_rm_watch:
7757 39b59763 aurel32
        ret = get_errno(sys_inotify_rm_watch(arg1, arg2));
7758 39b59763 aurel32
        break;
7759 39b59763 aurel32
#endif
7760 9007f0ef ths
7761 8ec9cf89 Nathan Froyd
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
7762 24e1003a aurel32
    case TARGET_NR_mq_open:
7763 24e1003a aurel32
        {
7764 24e1003a aurel32
            struct mq_attr posix_mq_attr;
7765 24e1003a aurel32
7766 24e1003a aurel32
            p = lock_user_string(arg1 - 1);
7767 24e1003a aurel32
            if (arg4 != 0)
7768 24e1003a aurel32
                copy_from_user_mq_attr (&posix_mq_attr, arg4);
7769 24e1003a aurel32
            ret = get_errno(mq_open(p, arg2, arg3, &posix_mq_attr));
7770 24e1003a aurel32
            unlock_user (p, arg1, 0);
7771 24e1003a aurel32
        }
7772 24e1003a aurel32
        break;
7773 24e1003a aurel32
7774 24e1003a aurel32
    case TARGET_NR_mq_unlink:
7775 24e1003a aurel32
        p = lock_user_string(arg1 - 1);
7776 24e1003a aurel32
        ret = get_errno(mq_unlink(p));
7777 24e1003a aurel32
        unlock_user (p, arg1, 0);
7778 24e1003a aurel32
        break;
7779 24e1003a aurel32
7780 24e1003a aurel32
    case TARGET_NR_mq_timedsend:
7781 24e1003a aurel32
        {
7782 24e1003a aurel32
            struct timespec ts;
7783 24e1003a aurel32
7784 24e1003a aurel32
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7785 24e1003a aurel32
            if (arg5 != 0) {
7786 24e1003a aurel32
                target_to_host_timespec(&ts, arg5);
7787 24e1003a aurel32
                ret = get_errno(mq_timedsend(arg1, p, arg3, arg4, &ts));
7788 24e1003a aurel32
                host_to_target_timespec(arg5, &ts);
7789 24e1003a aurel32
            }
7790 24e1003a aurel32
            else
7791 24e1003a aurel32
                ret = get_errno(mq_send(arg1, p, arg3, arg4));
7792 24e1003a aurel32
            unlock_user (p, arg2, arg3);
7793 24e1003a aurel32
        }
7794 24e1003a aurel32
        break;
7795 24e1003a aurel32
7796 24e1003a aurel32
    case TARGET_NR_mq_timedreceive:
7797 24e1003a aurel32
        {
7798 24e1003a aurel32
            struct timespec ts;
7799 24e1003a aurel32
            unsigned int prio;
7800 24e1003a aurel32
7801 24e1003a aurel32
            p = lock_user (VERIFY_READ, arg2, arg3, 1);
7802 24e1003a aurel32
            if (arg5 != 0) {
7803 24e1003a aurel32
                target_to_host_timespec(&ts, arg5);
7804 24e1003a aurel32
                ret = get_errno(mq_timedreceive(arg1, p, arg3, &prio, &ts));
7805 24e1003a aurel32
                host_to_target_timespec(arg5, &ts);
7806 24e1003a aurel32
            }
7807 24e1003a aurel32
            else
7808 24e1003a aurel32
                ret = get_errno(mq_receive(arg1, p, arg3, &prio));
7809 24e1003a aurel32
            unlock_user (p, arg2, arg3);
7810 24e1003a aurel32
            if (arg4 != 0)
7811 24e1003a aurel32
                put_user_u32(prio, arg4);
7812 24e1003a aurel32
        }
7813 24e1003a aurel32
        break;
7814 24e1003a aurel32
7815 24e1003a aurel32
    /* Not implemented for now... */
7816 24e1003a aurel32
/*     case TARGET_NR_mq_notify: */
7817 24e1003a aurel32
/*         break; */
7818 24e1003a aurel32
7819 24e1003a aurel32
    case TARGET_NR_mq_getsetattr:
7820 24e1003a aurel32
        {
7821 24e1003a aurel32
            struct mq_attr posix_mq_attr_in, posix_mq_attr_out;
7822 24e1003a aurel32
            ret = 0;
7823 24e1003a aurel32
            if (arg3 != 0) {
7824 24e1003a aurel32
                ret = mq_getattr(arg1, &posix_mq_attr_out);
7825 24e1003a aurel32
                copy_to_user_mq_attr(arg3, &posix_mq_attr_out);
7826 24e1003a aurel32
            }
7827 24e1003a aurel32
            if (arg2 != 0) {
7828 24e1003a aurel32
                copy_from_user_mq_attr(&posix_mq_attr_in, arg2);
7829 24e1003a aurel32
                ret |= mq_setattr(arg1, &posix_mq_attr_in, &posix_mq_attr_out);
7830 24e1003a aurel32
            }
7831 24e1003a aurel32
7832 24e1003a aurel32
        }
7833 24e1003a aurel32
        break;
7834 24e1003a aurel32
#endif
7835 24e1003a aurel32
7836 3ce34dfb vibisreenivasan
#ifdef CONFIG_SPLICE
7837 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_tee
7838 3ce34dfb vibisreenivasan
    case TARGET_NR_tee:
7839 3ce34dfb vibisreenivasan
        {
7840 3ce34dfb vibisreenivasan
            ret = get_errno(tee(arg1,arg2,arg3,arg4));
7841 3ce34dfb vibisreenivasan
        }
7842 3ce34dfb vibisreenivasan
        break;
7843 3ce34dfb vibisreenivasan
#endif
7844 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_splice
7845 3ce34dfb vibisreenivasan
    case TARGET_NR_splice:
7846 3ce34dfb vibisreenivasan
        {
7847 3ce34dfb vibisreenivasan
            loff_t loff_in, loff_out;
7848 3ce34dfb vibisreenivasan
            loff_t *ploff_in = NULL, *ploff_out = NULL;
7849 3ce34dfb vibisreenivasan
            if(arg2) {
7850 3ce34dfb vibisreenivasan
                get_user_u64(loff_in, arg2);
7851 3ce34dfb vibisreenivasan
                ploff_in = &loff_in;
7852 3ce34dfb vibisreenivasan
            }
7853 3ce34dfb vibisreenivasan
            if(arg4) {
7854 3ce34dfb vibisreenivasan
                get_user_u64(loff_out, arg2);
7855 3ce34dfb vibisreenivasan
                ploff_out = &loff_out;
7856 3ce34dfb vibisreenivasan
            }
7857 3ce34dfb vibisreenivasan
            ret = get_errno(splice(arg1, ploff_in, arg3, ploff_out, arg5, arg6));
7858 3ce34dfb vibisreenivasan
        }
7859 3ce34dfb vibisreenivasan
        break;
7860 3ce34dfb vibisreenivasan
#endif
7861 3ce34dfb vibisreenivasan
#ifdef TARGET_NR_vmsplice
7862 3ce34dfb vibisreenivasan
        case TARGET_NR_vmsplice:
7863 3ce34dfb vibisreenivasan
        {
7864 3ce34dfb vibisreenivasan
            int count = arg3;
7865 3ce34dfb vibisreenivasan
            struct iovec *vec;
7866 3ce34dfb vibisreenivasan
7867 3ce34dfb vibisreenivasan
            vec = alloca(count * sizeof(struct iovec));
7868 3ce34dfb vibisreenivasan
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
7869 3ce34dfb vibisreenivasan
                goto efault;
7870 3ce34dfb vibisreenivasan
            ret = get_errno(vmsplice(arg1, vec, count, arg4));
7871 3ce34dfb vibisreenivasan
            unlock_iovec(vec, arg2, count, 0);
7872 3ce34dfb vibisreenivasan
        }
7873 3ce34dfb vibisreenivasan
        break;
7874 3ce34dfb vibisreenivasan
#endif
7875 3ce34dfb vibisreenivasan
#endif /* CONFIG_SPLICE */
7876 c2882b96 Riku Voipio
#ifdef CONFIG_EVENTFD
7877 c2882b96 Riku Voipio
#if defined(TARGET_NR_eventfd)
7878 c2882b96 Riku Voipio
    case TARGET_NR_eventfd:
7879 c2882b96 Riku Voipio
        ret = get_errno(eventfd(arg1, 0));
7880 c2882b96 Riku Voipio
        break;
7881 c2882b96 Riku Voipio
#endif
7882 c2882b96 Riku Voipio
#if defined(TARGET_NR_eventfd2)
7883 c2882b96 Riku Voipio
    case TARGET_NR_eventfd2:
7884 c2882b96 Riku Voipio
        ret = get_errno(eventfd(arg1, arg2));
7885 c2882b96 Riku Voipio
        break;
7886 c2882b96 Riku Voipio
#endif
7887 c2882b96 Riku Voipio
#endif /* CONFIG_EVENTFD  */
7888 d0927938 Ulrich Hecht
#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
7889 d0927938 Ulrich Hecht
    case TARGET_NR_fallocate:
7890 d0927938 Ulrich Hecht
        ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
7891 d0927938 Ulrich Hecht
        break;
7892 d0927938 Ulrich Hecht
#endif
7893 c727f47d Peter Maydell
#if defined(CONFIG_SYNC_FILE_RANGE)
7894 c727f47d Peter Maydell
#if defined(TARGET_NR_sync_file_range)
7895 c727f47d Peter Maydell
    case TARGET_NR_sync_file_range:
7896 c727f47d Peter Maydell
#if TARGET_ABI_BITS == 32
7897 bfcedc57 Riku Voipio
#if defined(TARGET_MIPS)
7898 bfcedc57 Riku Voipio
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
7899 bfcedc57 Riku Voipio
                                        target_offset64(arg5, arg6), arg7));
7900 bfcedc57 Riku Voipio
#else
7901 c727f47d Peter Maydell
        ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
7902 c727f47d Peter Maydell
                                        target_offset64(arg4, arg5), arg6));
7903 bfcedc57 Riku Voipio
#endif /* !TARGET_MIPS */
7904 c727f47d Peter Maydell
#else
7905 c727f47d Peter Maydell
        ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
7906 c727f47d Peter Maydell
#endif
7907 c727f47d Peter Maydell
        break;
7908 c727f47d Peter Maydell
#endif
7909 c727f47d Peter Maydell
#if defined(TARGET_NR_sync_file_range2)
7910 c727f47d Peter Maydell
    case TARGET_NR_sync_file_range2:
7911 c727f47d Peter Maydell
        /* This is like sync_file_range but the arguments are reordered */
7912 c727f47d Peter Maydell
#if TARGET_ABI_BITS == 32
7913 c727f47d Peter Maydell
        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
7914 c727f47d Peter Maydell
                                        target_offset64(arg5, arg6), arg2));
7915 c727f47d Peter Maydell
#else
7916 c727f47d Peter Maydell
        ret = get_errno(sync_file_range(arg1, arg3, arg4, arg2));
7917 c727f47d Peter Maydell
#endif
7918 c727f47d Peter Maydell
        break;
7919 c727f47d Peter Maydell
#endif
7920 c727f47d Peter Maydell
#endif
7921 3b6edd16 Peter Maydell
#if defined(CONFIG_EPOLL)
7922 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_create)
7923 3b6edd16 Peter Maydell
    case TARGET_NR_epoll_create:
7924 3b6edd16 Peter Maydell
        ret = get_errno(epoll_create(arg1));
7925 3b6edd16 Peter Maydell
        break;
7926 3b6edd16 Peter Maydell
#endif
7927 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_create1) && defined(CONFIG_EPOLL_CREATE1)
7928 3b6edd16 Peter Maydell
    case TARGET_NR_epoll_create1:
7929 3b6edd16 Peter Maydell
        ret = get_errno(epoll_create1(arg1));
7930 3b6edd16 Peter Maydell
        break;
7931 3b6edd16 Peter Maydell
#endif
7932 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_ctl)
7933 3b6edd16 Peter Maydell
    case TARGET_NR_epoll_ctl:
7934 3b6edd16 Peter Maydell
    {
7935 3b6edd16 Peter Maydell
        struct epoll_event ep;
7936 3b6edd16 Peter Maydell
        struct epoll_event *epp = 0;
7937 3b6edd16 Peter Maydell
        if (arg4) {
7938 3b6edd16 Peter Maydell
            struct target_epoll_event *target_ep;
7939 3b6edd16 Peter Maydell
            if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
7940 3b6edd16 Peter Maydell
                goto efault;
7941 3b6edd16 Peter Maydell
            }
7942 3b6edd16 Peter Maydell
            ep.events = tswap32(target_ep->events);
7943 3b6edd16 Peter Maydell
            /* The epoll_data_t union is just opaque data to the kernel,
7944 3b6edd16 Peter Maydell
             * so we transfer all 64 bits across and need not worry what
7945 3b6edd16 Peter Maydell
             * actual data type it is.
7946 3b6edd16 Peter Maydell
             */
7947 3b6edd16 Peter Maydell
            ep.data.u64 = tswap64(target_ep->data.u64);
7948 3b6edd16 Peter Maydell
            unlock_user_struct(target_ep, arg4, 0);
7949 3b6edd16 Peter Maydell
            epp = &ep;
7950 3b6edd16 Peter Maydell
        }
7951 3b6edd16 Peter Maydell
        ret = get_errno(epoll_ctl(arg1, arg2, arg3, epp));
7952 3b6edd16 Peter Maydell
        break;
7953 3b6edd16 Peter Maydell
    }
7954 3b6edd16 Peter Maydell
#endif
7955 3b6edd16 Peter Maydell
7956 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_pwait) && defined(CONFIG_EPOLL_PWAIT)
7957 3b6edd16 Peter Maydell
#define IMPLEMENT_EPOLL_PWAIT
7958 3b6edd16 Peter Maydell
#endif
7959 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_wait) || defined(IMPLEMENT_EPOLL_PWAIT)
7960 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_wait)
7961 3b6edd16 Peter Maydell
    case TARGET_NR_epoll_wait:
7962 3b6edd16 Peter Maydell
#endif
7963 3b6edd16 Peter Maydell
#if defined(IMPLEMENT_EPOLL_PWAIT)
7964 3b6edd16 Peter Maydell
    case TARGET_NR_epoll_pwait:
7965 3b6edd16 Peter Maydell
#endif
7966 3b6edd16 Peter Maydell
    {
7967 3b6edd16 Peter Maydell
        struct target_epoll_event *target_ep;
7968 3b6edd16 Peter Maydell
        struct epoll_event *ep;
7969 3b6edd16 Peter Maydell
        int epfd = arg1;
7970 3b6edd16 Peter Maydell
        int maxevents = arg3;
7971 3b6edd16 Peter Maydell
        int timeout = arg4;
7972 3b6edd16 Peter Maydell
7973 3b6edd16 Peter Maydell
        target_ep = lock_user(VERIFY_WRITE, arg2,
7974 3b6edd16 Peter Maydell
                              maxevents * sizeof(struct target_epoll_event), 1);
7975 3b6edd16 Peter Maydell
        if (!target_ep) {
7976 3b6edd16 Peter Maydell
            goto efault;
7977 3b6edd16 Peter Maydell
        }
7978 3b6edd16 Peter Maydell
7979 3b6edd16 Peter Maydell
        ep = alloca(maxevents * sizeof(struct epoll_event));
7980 3b6edd16 Peter Maydell
7981 3b6edd16 Peter Maydell
        switch (num) {
7982 3b6edd16 Peter Maydell
#if defined(IMPLEMENT_EPOLL_PWAIT)
7983 3b6edd16 Peter Maydell
        case TARGET_NR_epoll_pwait:
7984 3b6edd16 Peter Maydell
        {
7985 3b6edd16 Peter Maydell
            target_sigset_t *target_set;
7986 3b6edd16 Peter Maydell
            sigset_t _set, *set = &_set;
7987 3b6edd16 Peter Maydell
7988 3b6edd16 Peter Maydell
            if (arg5) {
7989 3b6edd16 Peter Maydell
                target_set = lock_user(VERIFY_READ, arg5,
7990 3b6edd16 Peter Maydell
                                       sizeof(target_sigset_t), 1);
7991 3b6edd16 Peter Maydell
                if (!target_set) {
7992 3b6edd16 Peter Maydell
                    unlock_user(target_ep, arg2, 0);
7993 3b6edd16 Peter Maydell
                    goto efault;
7994 3b6edd16 Peter Maydell
                }
7995 3b6edd16 Peter Maydell
                target_to_host_sigset(set, target_set);
7996 3b6edd16 Peter Maydell
                unlock_user(target_set, arg5, 0);
7997 3b6edd16 Peter Maydell
            } else {
7998 3b6edd16 Peter Maydell
                set = NULL;
7999 3b6edd16 Peter Maydell
            }
8000 3b6edd16 Peter Maydell
8001 3b6edd16 Peter Maydell
            ret = get_errno(epoll_pwait(epfd, ep, maxevents, timeout, set));
8002 3b6edd16 Peter Maydell
            break;
8003 3b6edd16 Peter Maydell
        }
8004 3b6edd16 Peter Maydell
#endif
8005 3b6edd16 Peter Maydell
#if defined(TARGET_NR_epoll_wait)
8006 3b6edd16 Peter Maydell
        case TARGET_NR_epoll_wait:
8007 3b6edd16 Peter Maydell
            ret = get_errno(epoll_wait(epfd, ep, maxevents, timeout));
8008 3b6edd16 Peter Maydell
            break;
8009 3b6edd16 Peter Maydell
#endif
8010 3b6edd16 Peter Maydell
        default:
8011 3b6edd16 Peter Maydell
            ret = -TARGET_ENOSYS;
8012 3b6edd16 Peter Maydell
        }
8013 3b6edd16 Peter Maydell
        if (!is_error(ret)) {
8014 3b6edd16 Peter Maydell
            int i;
8015 3b6edd16 Peter Maydell
            for (i = 0; i < ret; i++) {
8016 3b6edd16 Peter Maydell
                target_ep[i].events = tswap32(ep[i].events);
8017 3b6edd16 Peter Maydell
                target_ep[i].data.u64 = tswap64(ep[i].data.u64);
8018 3b6edd16 Peter Maydell
            }
8019 3b6edd16 Peter Maydell
        }
8020 3b6edd16 Peter Maydell
        unlock_user(target_ep, arg2, ret * sizeof(struct target_epoll_event));
8021 3b6edd16 Peter Maydell
        break;
8022 3b6edd16 Peter Maydell
    }
8023 3b6edd16 Peter Maydell
#endif
8024 3b6edd16 Peter Maydell
#endif
8025 163a05a8 Peter Maydell
#ifdef TARGET_NR_prlimit64
8026 163a05a8 Peter Maydell
    case TARGET_NR_prlimit64:
8027 163a05a8 Peter Maydell
    {
8028 163a05a8 Peter Maydell
        /* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */
8029 163a05a8 Peter Maydell
        struct target_rlimit64 *target_rnew, *target_rold;
8030 163a05a8 Peter Maydell
        struct host_rlimit64 rnew, rold, *rnewp = 0;
8031 163a05a8 Peter Maydell
        if (arg3) {
8032 163a05a8 Peter Maydell
            if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
8033 163a05a8 Peter Maydell
                goto efault;
8034 163a05a8 Peter Maydell
            }
8035 163a05a8 Peter Maydell
            rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
8036 163a05a8 Peter Maydell
            rnew.rlim_max = tswap64(target_rnew->rlim_max);
8037 163a05a8 Peter Maydell
            unlock_user_struct(target_rnew, arg3, 0);
8038 163a05a8 Peter Maydell
            rnewp = &rnew;
8039 163a05a8 Peter Maydell
        }
8040 163a05a8 Peter Maydell
8041 163a05a8 Peter Maydell
        ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0));
8042 163a05a8 Peter Maydell
        if (!is_error(ret) && arg4) {
8043 163a05a8 Peter Maydell
            if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
8044 163a05a8 Peter Maydell
                goto efault;
8045 163a05a8 Peter Maydell
            }
8046 163a05a8 Peter Maydell
            target_rold->rlim_cur = tswap64(rold.rlim_cur);
8047 163a05a8 Peter Maydell
            target_rold->rlim_max = tswap64(rold.rlim_max);
8048 163a05a8 Peter Maydell
            unlock_user_struct(target_rold, arg4, 1);
8049 163a05a8 Peter Maydell
        }
8050 163a05a8 Peter Maydell
        break;
8051 163a05a8 Peter Maydell
    }
8052 163a05a8 Peter Maydell
#endif
8053 31e31b8a bellard
    default:
8054 31e31b8a bellard
    unimplemented:
8055 5cd4393b bellard
        gemu_log("qemu: Unsupported syscall: %d\n", num);
8056 4f2b1fe8 ths
#if defined(TARGET_NR_setxattr) || defined(TARGET_NR_get_thread_area) || defined(TARGET_NR_getdomainname) || defined(TARGET_NR_set_robust_list)
8057 5cd4393b bellard
    unimplemented_nowarn:
8058 80a9d035 bellard
#endif
8059 0da46a6e ths
        ret = -TARGET_ENOSYS;
8060 31e31b8a bellard
        break;
8061 31e31b8a bellard
    }
8062 579a97f7 bellard
fail:
8063 c573ff67 bellard
#ifdef DEBUG
8064 0bf9e31a Blue Swirl
    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
8065 c573ff67 bellard
#endif
8066 b92c47c1 ths
    if(do_strace)
8067 b92c47c1 ths
        print_syscall_ret(num, ret);
8068 31e31b8a bellard
    return ret;
8069 579a97f7 bellard
efault:
8070 579a97f7 bellard
    ret = -TARGET_EFAULT;
8071 579a97f7 bellard
    goto fail;
8072 31e31b8a bellard
}