Statistics
| Branch: | Revision:

root / linux-user / syscall.c @ 31e31b8a

History | View | Annotate | Download (42.1 kB)

1 31e31b8a bellard
/*
2 31e31b8a bellard
 *  Linux syscalls
3 31e31b8a bellard
 * 
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 31e31b8a bellard
 *  along with this program; if not, write to the Free Software
18 31e31b8a bellard
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 31e31b8a bellard
 */
20 31e31b8a bellard
#include <stdlib.h>
21 31e31b8a bellard
#include <stdio.h>
22 31e31b8a bellard
#include <stdarg.h>
23 31e31b8a bellard
#include <elf.h>
24 31e31b8a bellard
#include <endian.h>
25 31e31b8a bellard
#include <errno.h>
26 31e31b8a bellard
#include <unistd.h>
27 31e31b8a bellard
#include <fcntl.h>
28 31e31b8a bellard
#include <sys/types.h>
29 31e31b8a bellard
#include <sys/wait.h>
30 31e31b8a bellard
#include <sys/time.h>
31 31e31b8a bellard
#include <sys/stat.h>
32 31e31b8a bellard
#include <sys/mount.h>
33 31e31b8a bellard
#include <sys/resource.h>
34 31e31b8a bellard
#include <sys/mman.h>
35 31e31b8a bellard
#include <sys/swap.h>
36 31e31b8a bellard
#include <signal.h>
37 31e31b8a bellard
#include <sched.h>
38 31e31b8a bellard
#include <sys/socket.h>
39 31e31b8a bellard
#include <sys/uio.h>
40 31e31b8a bellard
#include <sys/user.h>
41 31e31b8a bellard
42 31e31b8a bellard
#define termios host_termios
43 31e31b8a bellard
#define winsize host_winsize
44 31e31b8a bellard
#define termio host_termio
45 31e31b8a bellard
46 31e31b8a bellard
#include <linux/termios.h>
47 31e31b8a bellard
#include <linux/unistd.h>
48 31e31b8a bellard
#include <linux/utsname.h>
49 31e31b8a bellard
#include <linux/cdrom.h>
50 31e31b8a bellard
#include <linux/hdreg.h>
51 31e31b8a bellard
#include <linux/soundcard.h>
52 31e31b8a bellard
53 31e31b8a bellard
#include "gemu.h"
54 31e31b8a bellard
55 31e31b8a bellard
#define DEBUG
56 31e31b8a bellard
57 31e31b8a bellard
#ifndef PAGE_SIZE
58 31e31b8a bellard
#define PAGE_SIZE 4096
59 31e31b8a bellard
#define PAGE_MASK ~(PAGE_SIZE - 1)
60 31e31b8a bellard
#endif
61 31e31b8a bellard
62 31e31b8a bellard
struct dirent {
63 31e31b8a bellard
        long            d_ino;
64 31e31b8a bellard
        long            d_off;
65 31e31b8a bellard
        unsigned short  d_reclen;
66 31e31b8a bellard
        char            d_name[256]; /* We must not include limits.h! */
67 31e31b8a bellard
};
68 31e31b8a bellard
69 31e31b8a bellard
#include "syscall_defs.h"
70 31e31b8a bellard
71 31e31b8a bellard
#ifdef TARGET_I386
72 31e31b8a bellard
#include "syscall-i386.h"
73 31e31b8a bellard
#endif
74 31e31b8a bellard
75 31e31b8a bellard
#define __NR_sys_uname __NR_uname
76 31e31b8a bellard
#define __NR_sys_getcwd __NR_getcwd
77 31e31b8a bellard
#define __NR_sys_statfs __NR_statfs
78 31e31b8a bellard
#define __NR_sys_fstatfs __NR_fstatfs
79 31e31b8a bellard
80 31e31b8a bellard
_syscall0(int, gettid)
81 31e31b8a bellard
_syscall1(int,sys_uname,struct new_utsname *,buf)
82 31e31b8a bellard
_syscall2(int,sys_getcwd,char *,buf,size_t,size)
83 31e31b8a bellard
_syscall3(int, getdents, uint, fd, struct dirent *, dirp, uint, count);
84 31e31b8a bellard
_syscall5(int, _llseek,  uint,  fd, ulong, hi, ulong, lo,
85 31e31b8a bellard
          loff_t *, res, uint, wh);
86 31e31b8a bellard
_syscall2(int,sys_statfs,const char *,path,struct statfs *,buf)
87 31e31b8a bellard
_syscall2(int,sys_fstatfs,int,fd,struct statfs *,buf)
88 31e31b8a bellard
89 31e31b8a bellard
static inline long get_errno(long ret)
90 31e31b8a bellard
{
91 31e31b8a bellard
    if (ret == -1)
92 31e31b8a bellard
        return -errno;
93 31e31b8a bellard
    else
94 31e31b8a bellard
        return ret;
95 31e31b8a bellard
}
96 31e31b8a bellard
97 31e31b8a bellard
static inline int is_error(long ret)
98 31e31b8a bellard
{
99 31e31b8a bellard
    return (unsigned long)ret >= (unsigned long)(-4096);
100 31e31b8a bellard
}
101 31e31b8a bellard
102 31e31b8a bellard
static char *target_brk;
103 31e31b8a bellard
static char *target_original_brk;
104 31e31b8a bellard
105 31e31b8a bellard
void target_set_brk(char *new_brk)
106 31e31b8a bellard
{
107 31e31b8a bellard
    target_brk = new_brk;
108 31e31b8a bellard
    target_original_brk = new_brk;
109 31e31b8a bellard
}
110 31e31b8a bellard
111 31e31b8a bellard
static long do_brk(char *new_brk)
112 31e31b8a bellard
{
113 31e31b8a bellard
    char *brk_page;
114 31e31b8a bellard
    long mapped_addr;
115 31e31b8a bellard
    int        new_alloc_size;
116 31e31b8a bellard
117 31e31b8a bellard
    if (!new_brk)
118 31e31b8a bellard
        return (long)target_brk;
119 31e31b8a bellard
    if (new_brk < target_original_brk)
120 31e31b8a bellard
        return -ENOMEM;
121 31e31b8a bellard
    
122 31e31b8a bellard
    brk_page = (char *)(((unsigned long)target_brk + PAGE_SIZE - 1) & PAGE_MASK);
123 31e31b8a bellard
124 31e31b8a bellard
    /* If the new brk is less than this, set it and we're done... */
125 31e31b8a bellard
    if (new_brk < brk_page) {
126 31e31b8a bellard
        target_brk = new_brk;
127 31e31b8a bellard
            return (long)target_brk;
128 31e31b8a bellard
    }
129 31e31b8a bellard
130 31e31b8a bellard
    /* We need to allocate more memory after the brk... */
131 31e31b8a bellard
    new_alloc_size = ((new_brk - brk_page + 1)+(PAGE_SIZE-1)) & PAGE_MASK;
132 31e31b8a bellard
    mapped_addr = get_errno((long)mmap((caddr_t)brk_page, new_alloc_size, 
133 31e31b8a bellard
                                       PROT_READ|PROT_WRITE,
134 31e31b8a bellard
                                       MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
135 31e31b8a bellard
    
136 31e31b8a bellard
    if (is_error(mapped_addr)) {
137 31e31b8a bellard
        return mapped_addr;
138 31e31b8a bellard
    } else {
139 31e31b8a bellard
        target_brk = new_brk;
140 31e31b8a bellard
            return (long)target_brk;
141 31e31b8a bellard
    }
142 31e31b8a bellard
}
143 31e31b8a bellard
144 31e31b8a bellard
static inline fd_set *target_to_host_fds(fd_set *fds, 
145 31e31b8a bellard
                                         target_long *target_fds, int n)
146 31e31b8a bellard
{
147 31e31b8a bellard
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
148 31e31b8a bellard
    return (fd_set *)target_fds;
149 31e31b8a bellard
#else
150 31e31b8a bellard
    int i, b;
151 31e31b8a bellard
    if (target_fds) {
152 31e31b8a bellard
        FD_ZERO(fds);
153 31e31b8a bellard
        for(i = 0;i < n; i++) {
154 31e31b8a bellard
            b = (tswapl(target_fds[i / TARGET_LONG_BITS]) >>
155 31e31b8a bellard
                 (i & (TARGET_LONG_BITS - 1))) & 1;
156 31e31b8a bellard
            if (b)
157 31e31b8a bellard
                FD_SET(i, fds);
158 31e31b8a bellard
        }
159 31e31b8a bellard
        return fds;
160 31e31b8a bellard
    } else {
161 31e31b8a bellard
        return NULL;
162 31e31b8a bellard
    }
163 31e31b8a bellard
#endif
164 31e31b8a bellard
}
165 31e31b8a bellard
166 31e31b8a bellard
static inline void host_to_target_fds(target_long *target_fds, 
167 31e31b8a bellard
                                      fd_set *fds, int n)
168 31e31b8a bellard
{
169 31e31b8a bellard
#if !defined(BSWP_NEEDED) && !defined(WORD_BIGENDIAN)
170 31e31b8a bellard
    /* nothing to do */
171 31e31b8a bellard
#else
172 31e31b8a bellard
    int i, nw, j, k;
173 31e31b8a bellard
    target_long v;
174 31e31b8a bellard
175 31e31b8a bellard
    if (target_fds) {
176 31e31b8a bellard
        nw = n / TARGET_LONG_BITS;
177 31e31b8a bellard
        k = 0;
178 31e31b8a bellard
        for(i = 0;i < nw; i++) {
179 31e31b8a bellard
            v = 0;
180 31e31b8a bellard
            for(j = 0; j < TARGET_LONG_BITS; j++) {
181 31e31b8a bellard
                v |= ((FD_ISSET(k, fds) != 0) << j);
182 31e31b8a bellard
                k++;
183 31e31b8a bellard
            }
184 31e31b8a bellard
            target_fds[i] = tswapl(v);
185 31e31b8a bellard
        }
186 31e31b8a bellard
    }
187 31e31b8a bellard
#endif
188 31e31b8a bellard
}
189 31e31b8a bellard
190 31e31b8a bellard
/* XXX: incorrect for some archs */
191 31e31b8a bellard
static void host_to_target_old_sigset(target_ulong *old_sigset, 
192 31e31b8a bellard
                                      const sigset_t *sigset)
193 31e31b8a bellard
{
194 31e31b8a bellard
    *old_sigset = tswap32(*(unsigned long *)sigset & 0xffffffff);
195 31e31b8a bellard
}
196 31e31b8a bellard
197 31e31b8a bellard
static void target_to_host_old_sigset(sigset_t *sigset, 
198 31e31b8a bellard
                                      const target_ulong *old_sigset)
199 31e31b8a bellard
{
200 31e31b8a bellard
    sigemptyset(sigset);
201 31e31b8a bellard
    *(unsigned long *)sigset = tswapl(*old_sigset);
202 31e31b8a bellard
}
203 31e31b8a bellard
204 31e31b8a bellard
205 31e31b8a bellard
static long do_select(long n, 
206 31e31b8a bellard
                      target_long *target_rfds, target_long *target_wfds, 
207 31e31b8a bellard
                      target_long *target_efds, struct target_timeval *target_tv)
208 31e31b8a bellard
{
209 31e31b8a bellard
    fd_set rfds, wfds, efds;
210 31e31b8a bellard
    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
211 31e31b8a bellard
    struct timeval tv, *tv_ptr;
212 31e31b8a bellard
    long ret;
213 31e31b8a bellard
214 31e31b8a bellard
    rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
215 31e31b8a bellard
    wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
216 31e31b8a bellard
    efds_ptr = target_to_host_fds(&efds, target_efds, n);
217 31e31b8a bellard
            
218 31e31b8a bellard
    if (target_tv) {
219 31e31b8a bellard
        tv.tv_sec = tswapl(target_tv->tv_sec);
220 31e31b8a bellard
        tv.tv_usec = tswapl(target_tv->tv_usec);
221 31e31b8a bellard
        tv_ptr = &tv;
222 31e31b8a bellard
    } else {
223 31e31b8a bellard
        tv_ptr = NULL;
224 31e31b8a bellard
    }
225 31e31b8a bellard
    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
226 31e31b8a bellard
    if (!is_error(ret)) {
227 31e31b8a bellard
        host_to_target_fds(target_rfds, rfds_ptr, n);
228 31e31b8a bellard
        host_to_target_fds(target_wfds, wfds_ptr, n);
229 31e31b8a bellard
        host_to_target_fds(target_efds, efds_ptr, n);
230 31e31b8a bellard
231 31e31b8a bellard
        if (target_tv) {
232 31e31b8a bellard
            target_tv->tv_sec = tswapl(tv.tv_sec);
233 31e31b8a bellard
            target_tv->tv_usec = tswapl(tv.tv_usec);
234 31e31b8a bellard
        }
235 31e31b8a bellard
    }
236 31e31b8a bellard
    return ret;
237 31e31b8a bellard
}
238 31e31b8a bellard
239 31e31b8a bellard
static long do_socketcall(int num, long *vptr)
240 31e31b8a bellard
{
241 31e31b8a bellard
    long ret;
242 31e31b8a bellard
243 31e31b8a bellard
    switch(num) {
244 31e31b8a bellard
    case SOCKOP_socket:
245 31e31b8a bellard
        ret = get_errno(socket(vptr[0], vptr[1], vptr[2]));
246 31e31b8a bellard
        break;
247 31e31b8a bellard
    case SOCKOP_bind:
248 31e31b8a bellard
        ret = get_errno(bind(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
249 31e31b8a bellard
        break;
250 31e31b8a bellard
    case SOCKOP_connect:
251 31e31b8a bellard
        ret = get_errno(connect(vptr[0], (struct sockaddr *)vptr[1], vptr[2]));
252 31e31b8a bellard
        break;
253 31e31b8a bellard
    case SOCKOP_listen:
254 31e31b8a bellard
        ret = get_errno(listen(vptr[0], vptr[1]));
255 31e31b8a bellard
        break;
256 31e31b8a bellard
    case SOCKOP_accept:
257 31e31b8a bellard
        {
258 31e31b8a bellard
            socklen_t size;
259 31e31b8a bellard
            size = tswap32(*(int32_t *)vptr[2]);
260 31e31b8a bellard
            ret = get_errno(accept(vptr[0], (struct sockaddr *)vptr[1], &size));
261 31e31b8a bellard
            if (!is_error(ret)) 
262 31e31b8a bellard
                *(int32_t *)vptr[2] = size;
263 31e31b8a bellard
        }
264 31e31b8a bellard
        break;
265 31e31b8a bellard
    case SOCKOP_getsockname:
266 31e31b8a bellard
        {
267 31e31b8a bellard
            socklen_t size;
268 31e31b8a bellard
            size = tswap32(*(int32_t *)vptr[2]);
269 31e31b8a bellard
            ret = get_errno(getsockname(vptr[0], (struct sockaddr *)vptr[1], &size));
270 31e31b8a bellard
            if (!is_error(ret)) 
271 31e31b8a bellard
                *(int32_t *)vptr[2] = size;
272 31e31b8a bellard
        }
273 31e31b8a bellard
        break;
274 31e31b8a bellard
    case SOCKOP_getpeername:
275 31e31b8a bellard
        {
276 31e31b8a bellard
            socklen_t size;
277 31e31b8a bellard
            size = tswap32(*(int32_t *)vptr[2]);
278 31e31b8a bellard
            ret = get_errno(getpeername(vptr[0], (struct sockaddr *)vptr[1], &size));
279 31e31b8a bellard
            if (!is_error(ret)) 
280 31e31b8a bellard
                *(int32_t *)vptr[2] = size;
281 31e31b8a bellard
        }
282 31e31b8a bellard
        break;
283 31e31b8a bellard
    case SOCKOP_socketpair:
284 31e31b8a bellard
        {
285 31e31b8a bellard
            int tab[2];
286 31e31b8a bellard
            int32_t *target_tab = (int32_t *)vptr[3];
287 31e31b8a bellard
            ret = get_errno(socketpair(vptr[0], vptr[1], vptr[2], tab));
288 31e31b8a bellard
            if (!is_error(ret)) {
289 31e31b8a bellard
                target_tab[0] = tswap32(tab[0]);
290 31e31b8a bellard
                target_tab[1] = tswap32(tab[1]);
291 31e31b8a bellard
            }
292 31e31b8a bellard
        }
293 31e31b8a bellard
        break;
294 31e31b8a bellard
    case SOCKOP_send:
295 31e31b8a bellard
        ret = get_errno(send(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
296 31e31b8a bellard
        break;
297 31e31b8a bellard
    case SOCKOP_recv:
298 31e31b8a bellard
        ret = get_errno(recv(vptr[0], (void *)vptr[1], vptr[2], vptr[3]));
299 31e31b8a bellard
        break;
300 31e31b8a bellard
    case SOCKOP_sendto:
301 31e31b8a bellard
        ret = get_errno(sendto(vptr[0], (void *)vptr[1], vptr[2], vptr[3], 
302 31e31b8a bellard
                               (struct sockaddr *)vptr[4], vptr[5]));
303 31e31b8a bellard
        break;
304 31e31b8a bellard
    case SOCKOP_recvfrom:
305 31e31b8a bellard
        {
306 31e31b8a bellard
            socklen_t size;
307 31e31b8a bellard
            size = tswap32(*(int32_t *)vptr[5]);
308 31e31b8a bellard
            ret = get_errno(recvfrom(vptr[0], (void *)vptr[1], vptr[2], 
309 31e31b8a bellard
                                     vptr[3], (struct sockaddr *)vptr[4], &size));
310 31e31b8a bellard
            if (!is_error(ret)) 
311 31e31b8a bellard
                *(int32_t *)vptr[5] = size;
312 31e31b8a bellard
        }
313 31e31b8a bellard
        break;
314 31e31b8a bellard
    case SOCKOP_shutdown:
315 31e31b8a bellard
        ret = get_errno(shutdown(vptr[0], vptr[1]));
316 31e31b8a bellard
        break;
317 31e31b8a bellard
    case SOCKOP_sendmsg:
318 31e31b8a bellard
    case SOCKOP_recvmsg:
319 31e31b8a bellard
    case SOCKOP_setsockopt:
320 31e31b8a bellard
    case SOCKOP_getsockopt:
321 31e31b8a bellard
    default:
322 31e31b8a bellard
        gemu_log("Unsupported socketcall: %d\n", num);
323 31e31b8a bellard
        ret = -ENOSYS;
324 31e31b8a bellard
        break;
325 31e31b8a bellard
    }
326 31e31b8a bellard
    return ret;
327 31e31b8a bellard
}
328 31e31b8a bellard
329 31e31b8a bellard
/* kernel structure types definitions */
330 31e31b8a bellard
#define IFNAMSIZ        16
331 31e31b8a bellard
332 31e31b8a bellard
#define STRUCT(name, list...) STRUCT_ ## name,
333 31e31b8a bellard
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
334 31e31b8a bellard
enum {
335 31e31b8a bellard
#include "syscall_types.h"
336 31e31b8a bellard
};
337 31e31b8a bellard
#undef STRUCT
338 31e31b8a bellard
#undef STRUCT_SPECIAL
339 31e31b8a bellard
340 31e31b8a bellard
#define STRUCT(name, list...) const argtype struct_ ## name ## _def[] = { list, TYPE_NULL };
341 31e31b8a bellard
#define STRUCT_SPECIAL(name)
342 31e31b8a bellard
#include "syscall_types.h"
343 31e31b8a bellard
#undef STRUCT
344 31e31b8a bellard
#undef STRUCT_SPECIAL
345 31e31b8a bellard
346 31e31b8a bellard
typedef struct IOCTLEntry {
347 31e31b8a bellard
    int target_cmd;
348 31e31b8a bellard
    int host_cmd;
349 31e31b8a bellard
    const char *name;
350 31e31b8a bellard
    int access;
351 31e31b8a bellard
    const argtype arg_type[3];
352 31e31b8a bellard
} IOCTLEntry;
353 31e31b8a bellard
354 31e31b8a bellard
#define IOC_R 0x0001
355 31e31b8a bellard
#define IOC_W 0x0002
356 31e31b8a bellard
#define IOC_RW (IOC_R | IOC_W)
357 31e31b8a bellard
358 31e31b8a bellard
#define MAX_STRUCT_SIZE 4096
359 31e31b8a bellard
360 31e31b8a bellard
const IOCTLEntry ioctl_entries[] = {
361 31e31b8a bellard
#define IOCTL(cmd, access, types...) \
362 31e31b8a bellard
    { TARGET_ ## cmd, cmd, #cmd, access, { types } },
363 31e31b8a bellard
#include "ioctls.h"
364 31e31b8a bellard
    { 0, 0, },
365 31e31b8a bellard
};
366 31e31b8a bellard
367 31e31b8a bellard
static long do_ioctl(long fd, long cmd, long arg)
368 31e31b8a bellard
{
369 31e31b8a bellard
    const IOCTLEntry *ie;
370 31e31b8a bellard
    const argtype *arg_type;
371 31e31b8a bellard
    long ret;
372 31e31b8a bellard
    uint8_t buf_temp[MAX_STRUCT_SIZE];
373 31e31b8a bellard
374 31e31b8a bellard
    ie = ioctl_entries;
375 31e31b8a bellard
    for(;;) {
376 31e31b8a bellard
        if (ie->target_cmd == 0) {
377 31e31b8a bellard
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
378 31e31b8a bellard
            return -ENOSYS;
379 31e31b8a bellard
        }
380 31e31b8a bellard
        if (ie->target_cmd == cmd)
381 31e31b8a bellard
            break;
382 31e31b8a bellard
        ie++;
383 31e31b8a bellard
    }
384 31e31b8a bellard
    arg_type = ie->arg_type;
385 31e31b8a bellard
    //    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
386 31e31b8a bellard
    switch(arg_type[0]) {
387 31e31b8a bellard
    case TYPE_NULL:
388 31e31b8a bellard
        /* no argument */
389 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd));
390 31e31b8a bellard
        break;
391 31e31b8a bellard
    case TYPE_PTRVOID:
392 31e31b8a bellard
    case TYPE_INT:
393 31e31b8a bellard
        /* int argment */
394 31e31b8a bellard
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
395 31e31b8a bellard
        break;
396 31e31b8a bellard
    case TYPE_PTR:
397 31e31b8a bellard
        arg_type++;
398 31e31b8a bellard
        switch(ie->access) {
399 31e31b8a bellard
        case IOC_R:
400 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
401 31e31b8a bellard
            if (!is_error(ret)) {
402 31e31b8a bellard
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
403 31e31b8a bellard
            }
404 31e31b8a bellard
            break;
405 31e31b8a bellard
        case IOC_W:
406 31e31b8a bellard
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
407 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
408 31e31b8a bellard
            break;
409 31e31b8a bellard
        default:
410 31e31b8a bellard
        case IOC_RW:
411 31e31b8a bellard
            thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
412 31e31b8a bellard
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
413 31e31b8a bellard
            if (!is_error(ret)) {
414 31e31b8a bellard
                thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
415 31e31b8a bellard
            }
416 31e31b8a bellard
            break;
417 31e31b8a bellard
        }
418 31e31b8a bellard
        break;
419 31e31b8a bellard
    default:
420 31e31b8a bellard
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
421 31e31b8a bellard
        ret = -ENOSYS;
422 31e31b8a bellard
        break;
423 31e31b8a bellard
    }
424 31e31b8a bellard
    return ret;
425 31e31b8a bellard
}
426 31e31b8a bellard
427 31e31b8a bellard
bitmask_transtbl iflag_tbl[] = {
428 31e31b8a bellard
        { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK },
429 31e31b8a bellard
        { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT },
430 31e31b8a bellard
        { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR },
431 31e31b8a bellard
        { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK },
432 31e31b8a bellard
        { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK },
433 31e31b8a bellard
        { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP },
434 31e31b8a bellard
        { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR },
435 31e31b8a bellard
        { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR },
436 31e31b8a bellard
        { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL },
437 31e31b8a bellard
        { TARGET_IUCLC, TARGET_IUCLC, IUCLC, IUCLC },
438 31e31b8a bellard
        { TARGET_IXON, TARGET_IXON, IXON, IXON },
439 31e31b8a bellard
        { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY },
440 31e31b8a bellard
        { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
441 31e31b8a bellard
        { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
442 31e31b8a bellard
        { 0, 0, 0, 0 }
443 31e31b8a bellard
};
444 31e31b8a bellard
445 31e31b8a bellard
bitmask_transtbl oflag_tbl[] = {
446 31e31b8a bellard
        { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST },
447 31e31b8a bellard
        { TARGET_OLCUC, TARGET_OLCUC, OLCUC, OLCUC },
448 31e31b8a bellard
        { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR },
449 31e31b8a bellard
        { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL },
450 31e31b8a bellard
        { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR },
451 31e31b8a bellard
        { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET },
452 31e31b8a bellard
        { TARGET_OFILL, TARGET_OFILL, OFILL, OFILL },
453 31e31b8a bellard
        { TARGET_OFDEL, TARGET_OFDEL, OFDEL, OFDEL },
454 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL0, NLDLY, NL0 },
455 31e31b8a bellard
        { TARGET_NLDLY, TARGET_NL1, NLDLY, NL1 },
456 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR0, CRDLY, CR0 },
457 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR1, CRDLY, CR1 },
458 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR2, CRDLY, CR2 },
459 31e31b8a bellard
        { TARGET_CRDLY, TARGET_CR3, CRDLY, CR3 },
460 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 },
461 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB1, TABDLY, TAB1 },
462 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB2, TABDLY, TAB2 },
463 31e31b8a bellard
        { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 },
464 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS0, BSDLY, BS0 },
465 31e31b8a bellard
        { TARGET_BSDLY, TARGET_BS1, BSDLY, BS1 },
466 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT0, VTDLY, VT0 },
467 31e31b8a bellard
        { TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
468 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
469 31e31b8a bellard
        { TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
470 31e31b8a bellard
        { 0, 0, 0, 0 }
471 31e31b8a bellard
};
472 31e31b8a bellard
473 31e31b8a bellard
bitmask_transtbl cflag_tbl[] = {
474 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B0, CBAUD, B0 },
475 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B50, CBAUD, B50 },
476 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B75, CBAUD, B75 },
477 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B110, CBAUD, B110 },
478 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B134, CBAUD, B134 },
479 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B150, CBAUD, B150 },
480 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B200, CBAUD, B200 },
481 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B300, CBAUD, B300 },
482 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B600, CBAUD, B600 },
483 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1200, CBAUD, B1200 },
484 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B1800, CBAUD, B1800 },
485 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B2400, CBAUD, B2400 },
486 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B4800, CBAUD, B4800 },
487 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B9600, CBAUD, B9600 },
488 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B19200, CBAUD, B19200 },
489 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B38400, CBAUD, B38400 },
490 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B57600, CBAUD, B57600 },
491 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B115200, CBAUD, B115200 },
492 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B230400, CBAUD, B230400 },
493 31e31b8a bellard
        { TARGET_CBAUD, TARGET_B460800, CBAUD, B460800 },
494 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 },
495 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 },
496 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 },
497 31e31b8a bellard
        { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 },
498 31e31b8a bellard
        { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB },
499 31e31b8a bellard
        { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD },
500 31e31b8a bellard
        { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB },
501 31e31b8a bellard
        { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD },
502 31e31b8a bellard
        { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
503 31e31b8a bellard
        { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
504 31e31b8a bellard
        { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
505 31e31b8a bellard
        { 0, 0, 0, 0 }
506 31e31b8a bellard
};
507 31e31b8a bellard
508 31e31b8a bellard
bitmask_transtbl lflag_tbl[] = {
509 31e31b8a bellard
        { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG },
510 31e31b8a bellard
        { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON },
511 31e31b8a bellard
        { TARGET_XCASE, TARGET_XCASE, XCASE, XCASE },
512 31e31b8a bellard
        { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO },
513 31e31b8a bellard
        { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE },
514 31e31b8a bellard
        { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK },
515 31e31b8a bellard
        { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL },
516 31e31b8a bellard
        { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH },
517 31e31b8a bellard
        { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP },
518 31e31b8a bellard
        { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL },
519 31e31b8a bellard
        { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT },
520 31e31b8a bellard
        { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE },
521 31e31b8a bellard
        { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO },
522 31e31b8a bellard
        { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
523 31e31b8a bellard
        { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
524 31e31b8a bellard
        { 0, 0, 0, 0 }
525 31e31b8a bellard
};
526 31e31b8a bellard
527 31e31b8a bellard
static void target_to_host_termios (void *dst, const void *src)
528 31e31b8a bellard
{
529 31e31b8a bellard
    struct host_termios *host = dst;
530 31e31b8a bellard
    const struct target_termios *target = src;
531 31e31b8a bellard
    
532 31e31b8a bellard
    host->c_iflag = 
533 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl);
534 31e31b8a bellard
    host->c_oflag = 
535 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl);
536 31e31b8a bellard
    host->c_cflag = 
537 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl);
538 31e31b8a bellard
    host->c_lflag = 
539 31e31b8a bellard
        target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl);
540 31e31b8a bellard
    host->c_line = target->c_line;
541 31e31b8a bellard
    
542 31e31b8a bellard
    host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; 
543 31e31b8a bellard
    host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; 
544 31e31b8a bellard
    host->c_cc[VERASE] = target->c_cc[TARGET_VERASE];       
545 31e31b8a bellard
    host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; 
546 31e31b8a bellard
    host->c_cc[VEOF] = target->c_cc[TARGET_VEOF];   
547 31e31b8a bellard
    host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; 
548 31e31b8a bellard
    host->c_cc[VMIN] = target->c_cc[TARGET_VMIN];   
549 31e31b8a bellard
    host->c_cc[VSWTC] = target->c_cc[TARGET_VSWTC]; 
550 31e31b8a bellard
    host->c_cc[VSTART] = target->c_cc[TARGET_VSTART];       
551 31e31b8a bellard
    host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; 
552 31e31b8a bellard
    host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; 
553 31e31b8a bellard
    host->c_cc[VEOL] = target->c_cc[TARGET_VEOL];   
554 31e31b8a bellard
    host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT];   
555 31e31b8a bellard
    host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD];   
556 31e31b8a bellard
    host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE];     
557 31e31b8a bellard
    host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT];       
558 31e31b8a bellard
    host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; 
559 31e31b8a bellard
}
560 31e31b8a bellard
  
561 31e31b8a bellard
static void host_to_target_termios (void *dst, const void *src)
562 31e31b8a bellard
{
563 31e31b8a bellard
    struct target_termios *target = dst;
564 31e31b8a bellard
    const struct host_termios *host = src;
565 31e31b8a bellard
566 31e31b8a bellard
    target->c_iflag = 
567 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl));
568 31e31b8a bellard
    target->c_oflag = 
569 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl));
570 31e31b8a bellard
    target->c_cflag = 
571 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl));
572 31e31b8a bellard
    target->c_lflag = 
573 31e31b8a bellard
        tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl));
574 31e31b8a bellard
    target->c_line = host->c_line;
575 31e31b8a bellard
  
576 31e31b8a bellard
    target->c_cc[TARGET_VINTR] = host->c_cc[VINTR];
577 31e31b8a bellard
    target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT];
578 31e31b8a bellard
    target->c_cc[TARGET_VERASE] = host->c_cc[VERASE];
579 31e31b8a bellard
    target->c_cc[TARGET_VKILL] = host->c_cc[VKILL];
580 31e31b8a bellard
    target->c_cc[TARGET_VEOF] = host->c_cc[VEOF];
581 31e31b8a bellard
    target->c_cc[TARGET_VTIME] = host->c_cc[VTIME];
582 31e31b8a bellard
    target->c_cc[TARGET_VMIN] = host->c_cc[VMIN];
583 31e31b8a bellard
    target->c_cc[TARGET_VSWTC] = host->c_cc[VSWTC];
584 31e31b8a bellard
    target->c_cc[TARGET_VSTART] = host->c_cc[VSTART];
585 31e31b8a bellard
    target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP];
586 31e31b8a bellard
    target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP];
587 31e31b8a bellard
    target->c_cc[TARGET_VEOL] = host->c_cc[VEOL];
588 31e31b8a bellard
    target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT];
589 31e31b8a bellard
    target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD];
590 31e31b8a bellard
    target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE];
591 31e31b8a bellard
    target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT];
592 31e31b8a bellard
    target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2];
593 31e31b8a bellard
}
594 31e31b8a bellard
595 31e31b8a bellard
StructEntry struct_termios_def = {
596 31e31b8a bellard
    .convert = { host_to_target_termios, target_to_host_termios },
597 31e31b8a bellard
    .size = { sizeof(struct target_termios), sizeof(struct host_termios) },
598 31e31b8a bellard
    .align = { __alignof__(struct target_termios), __alignof__(struct host_termios) },
599 31e31b8a bellard
};
600 31e31b8a bellard
601 31e31b8a bellard
void syscall_init(void)
602 31e31b8a bellard
{
603 31e31b8a bellard
#define STRUCT(name, list...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); 
604 31e31b8a bellard
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); 
605 31e31b8a bellard
#include "syscall_types.h"
606 31e31b8a bellard
#undef STRUCT
607 31e31b8a bellard
#undef STRUCT_SPECIAL
608 31e31b8a bellard
}
609 31e31b8a bellard
                                 
610 31e31b8a bellard
long do_syscall(int num, long arg1, long arg2, long arg3, 
611 31e31b8a bellard
                long arg4, long arg5, long arg6)
612 31e31b8a bellard
{
613 31e31b8a bellard
    long ret;
614 31e31b8a bellard
    struct stat st;
615 31e31b8a bellard
    struct statfs *stfs;
616 31e31b8a bellard
    
617 31e31b8a bellard
    //    gemu_log("syscall %d\n", num);
618 31e31b8a bellard
    switch(num) {
619 31e31b8a bellard
    case TARGET_NR_exit:
620 31e31b8a bellard
        _exit(arg1);
621 31e31b8a bellard
        ret = 0; /* avoid warning */
622 31e31b8a bellard
        break;
623 31e31b8a bellard
    case TARGET_NR_read:
624 31e31b8a bellard
        ret = get_errno(read(arg1, (void *)arg2, arg3));
625 31e31b8a bellard
        break;
626 31e31b8a bellard
    case TARGET_NR_write:
627 31e31b8a bellard
        ret = get_errno(write(arg1, (void *)arg2, arg3));
628 31e31b8a bellard
        break;
629 31e31b8a bellard
    case TARGET_NR_open:
630 31e31b8a bellard
        ret = get_errno(open((const char *)arg1, arg2, arg3));
631 31e31b8a bellard
        break;
632 31e31b8a bellard
    case TARGET_NR_close:
633 31e31b8a bellard
        ret = get_errno(close(arg1));
634 31e31b8a bellard
        break;
635 31e31b8a bellard
    case TARGET_NR_brk:
636 31e31b8a bellard
        ret = do_brk((char *)arg1);
637 31e31b8a bellard
        break;
638 31e31b8a bellard
    case TARGET_NR_fork:
639 31e31b8a bellard
        ret = get_errno(fork());
640 31e31b8a bellard
        break;
641 31e31b8a bellard
    case TARGET_NR_waitpid:
642 31e31b8a bellard
        {
643 31e31b8a bellard
            int *status = (int *)arg2;
644 31e31b8a bellard
            ret = get_errno(waitpid(arg1, status, arg3));
645 31e31b8a bellard
            if (!is_error(ret) && status)
646 31e31b8a bellard
                tswapls((long *)&status);
647 31e31b8a bellard
        }
648 31e31b8a bellard
        break;
649 31e31b8a bellard
    case TARGET_NR_creat:
650 31e31b8a bellard
        ret = get_errno(creat((const char *)arg1, arg2));
651 31e31b8a bellard
        break;
652 31e31b8a bellard
    case TARGET_NR_link:
653 31e31b8a bellard
        ret = get_errno(link((const char *)arg1, (const char *)arg2));
654 31e31b8a bellard
        break;
655 31e31b8a bellard
    case TARGET_NR_unlink:
656 31e31b8a bellard
        ret = get_errno(unlink((const char *)arg1));
657 31e31b8a bellard
        break;
658 31e31b8a bellard
    case TARGET_NR_execve:
659 31e31b8a bellard
        ret = get_errno(execve((const char *)arg1, (void *)arg2, (void *)arg3));
660 31e31b8a bellard
        break;
661 31e31b8a bellard
    case TARGET_NR_chdir:
662 31e31b8a bellard
        ret = get_errno(chdir((const char *)arg1));
663 31e31b8a bellard
        break;
664 31e31b8a bellard
    case TARGET_NR_time:
665 31e31b8a bellard
        {
666 31e31b8a bellard
            int *time_ptr = (int *)arg1;
667 31e31b8a bellard
            ret = get_errno(time((time_t *)time_ptr));
668 31e31b8a bellard
            if (!is_error(ret) && time_ptr)
669 31e31b8a bellard
                tswap32s(time_ptr);
670 31e31b8a bellard
        }
671 31e31b8a bellard
        break;
672 31e31b8a bellard
    case TARGET_NR_mknod:
673 31e31b8a bellard
        ret = get_errno(mknod((const char *)arg1, arg2, arg3));
674 31e31b8a bellard
        break;
675 31e31b8a bellard
    case TARGET_NR_chmod:
676 31e31b8a bellard
        ret = get_errno(chmod((const char *)arg1, arg2));
677 31e31b8a bellard
        break;
678 31e31b8a bellard
    case TARGET_NR_lchown:
679 31e31b8a bellard
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
680 31e31b8a bellard
        break;
681 31e31b8a bellard
    case TARGET_NR_break:
682 31e31b8a bellard
        goto unimplemented;
683 31e31b8a bellard
    case TARGET_NR_oldstat:
684 31e31b8a bellard
        goto unimplemented;
685 31e31b8a bellard
    case TARGET_NR_lseek:
686 31e31b8a bellard
        ret = get_errno(lseek(arg1, arg2, arg3));
687 31e31b8a bellard
        break;
688 31e31b8a bellard
    case TARGET_NR_getpid:
689 31e31b8a bellard
        ret = get_errno(getpid());
690 31e31b8a bellard
        break;
691 31e31b8a bellard
    case TARGET_NR_mount:
692 31e31b8a bellard
        /* need to look at the data field */
693 31e31b8a bellard
        goto unimplemented;
694 31e31b8a bellard
    case TARGET_NR_umount:
695 31e31b8a bellard
        ret = get_errno(umount((const char *)arg1));
696 31e31b8a bellard
        break;
697 31e31b8a bellard
    case TARGET_NR_setuid:
698 31e31b8a bellard
        ret = get_errno(setuid(arg1));
699 31e31b8a bellard
        break;
700 31e31b8a bellard
    case TARGET_NR_getuid:
701 31e31b8a bellard
        ret = get_errno(getuid());
702 31e31b8a bellard
        break;
703 31e31b8a bellard
    case TARGET_NR_stime:
704 31e31b8a bellard
        {
705 31e31b8a bellard
            int *time_ptr = (int *)arg1;
706 31e31b8a bellard
            if (time_ptr)
707 31e31b8a bellard
                tswap32s(time_ptr);
708 31e31b8a bellard
            ret = get_errno(stime((time_t *)time_ptr));
709 31e31b8a bellard
        }
710 31e31b8a bellard
        break;
711 31e31b8a bellard
    case TARGET_NR_ptrace:
712 31e31b8a bellard
        goto unimplemented;
713 31e31b8a bellard
    case TARGET_NR_alarm:
714 31e31b8a bellard
        ret = alarm(arg1);
715 31e31b8a bellard
        break;
716 31e31b8a bellard
    case TARGET_NR_oldfstat:
717 31e31b8a bellard
        goto unimplemented;
718 31e31b8a bellard
    case TARGET_NR_pause:
719 31e31b8a bellard
        ret = get_errno(pause());
720 31e31b8a bellard
        break;
721 31e31b8a bellard
    case TARGET_NR_utime:
722 31e31b8a bellard
        goto unimplemented;
723 31e31b8a bellard
    case TARGET_NR_stty:
724 31e31b8a bellard
        goto unimplemented;
725 31e31b8a bellard
    case TARGET_NR_gtty:
726 31e31b8a bellard
        goto unimplemented;
727 31e31b8a bellard
    case TARGET_NR_access:
728 31e31b8a bellard
        ret = get_errno(access((const char *)arg1, arg2));
729 31e31b8a bellard
        break;
730 31e31b8a bellard
    case TARGET_NR_nice:
731 31e31b8a bellard
        ret = get_errno(nice(arg1));
732 31e31b8a bellard
        break;
733 31e31b8a bellard
    case TARGET_NR_ftime:
734 31e31b8a bellard
        goto unimplemented;
735 31e31b8a bellard
    case TARGET_NR_sync:
736 31e31b8a bellard
        ret = get_errno(sync());
737 31e31b8a bellard
        break;
738 31e31b8a bellard
    case TARGET_NR_kill:
739 31e31b8a bellard
        ret = get_errno(kill(arg1, arg2));
740 31e31b8a bellard
        break;
741 31e31b8a bellard
    case TARGET_NR_rename:
742 31e31b8a bellard
        ret = get_errno(rename((const char *)arg1, (const char *)arg2));
743 31e31b8a bellard
        break;
744 31e31b8a bellard
    case TARGET_NR_mkdir:
745 31e31b8a bellard
        ret = get_errno(mkdir((const char *)arg1, arg2));
746 31e31b8a bellard
        break;
747 31e31b8a bellard
    case TARGET_NR_rmdir:
748 31e31b8a bellard
        ret = get_errno(rmdir((const char *)arg1));
749 31e31b8a bellard
        break;
750 31e31b8a bellard
    case TARGET_NR_dup:
751 31e31b8a bellard
        ret = get_errno(dup(arg1));
752 31e31b8a bellard
        break;
753 31e31b8a bellard
    case TARGET_NR_pipe:
754 31e31b8a bellard
        {
755 31e31b8a bellard
            int *pipe_ptr = (int *)arg1;
756 31e31b8a bellard
            ret = get_errno(pipe(pipe_ptr));
757 31e31b8a bellard
            if (!is_error(ret)) {
758 31e31b8a bellard
                tswap32s(&pipe_ptr[0]);
759 31e31b8a bellard
                tswap32s(&pipe_ptr[1]);
760 31e31b8a bellard
            }
761 31e31b8a bellard
        }
762 31e31b8a bellard
        break;
763 31e31b8a bellard
    case TARGET_NR_times:
764 31e31b8a bellard
        goto unimplemented;
765 31e31b8a bellard
    case TARGET_NR_prof:
766 31e31b8a bellard
        goto unimplemented;
767 31e31b8a bellard
    case TARGET_NR_setgid:
768 31e31b8a bellard
        ret = get_errno(setgid(arg1));
769 31e31b8a bellard
        break;
770 31e31b8a bellard
    case TARGET_NR_getgid:
771 31e31b8a bellard
        ret = get_errno(getgid());
772 31e31b8a bellard
        break;
773 31e31b8a bellard
    case TARGET_NR_signal:
774 31e31b8a bellard
        goto unimplemented;
775 31e31b8a bellard
    case TARGET_NR_geteuid:
776 31e31b8a bellard
        ret = get_errno(geteuid());
777 31e31b8a bellard
        break;
778 31e31b8a bellard
    case TARGET_NR_getegid:
779 31e31b8a bellard
        ret = get_errno(getegid());
780 31e31b8a bellard
        break;
781 31e31b8a bellard
    case TARGET_NR_acct:
782 31e31b8a bellard
        goto unimplemented;
783 31e31b8a bellard
    case TARGET_NR_umount2:
784 31e31b8a bellard
        ret = get_errno(umount2((const char *)arg1, arg2));
785 31e31b8a bellard
        break;
786 31e31b8a bellard
    case TARGET_NR_lock:
787 31e31b8a bellard
        goto unimplemented;
788 31e31b8a bellard
    case TARGET_NR_ioctl:
789 31e31b8a bellard
        ret = do_ioctl(arg1, arg2, arg3);
790 31e31b8a bellard
        break;
791 31e31b8a bellard
    case TARGET_NR_fcntl:
792 31e31b8a bellard
        switch(arg2) {
793 31e31b8a bellard
        case F_GETLK:
794 31e31b8a bellard
        case F_SETLK:
795 31e31b8a bellard
        case F_SETLKW:
796 31e31b8a bellard
            goto unimplemented;
797 31e31b8a bellard
        default:
798 31e31b8a bellard
            ret = get_errno(fcntl(arg1, arg2, arg3));
799 31e31b8a bellard
            break;
800 31e31b8a bellard
        }
801 31e31b8a bellard
        break;
802 31e31b8a bellard
    case TARGET_NR_mpx:
803 31e31b8a bellard
        goto unimplemented;
804 31e31b8a bellard
    case TARGET_NR_setpgid:
805 31e31b8a bellard
        ret = get_errno(setpgid(arg1, arg2));
806 31e31b8a bellard
        break;
807 31e31b8a bellard
    case TARGET_NR_ulimit:
808 31e31b8a bellard
        goto unimplemented;
809 31e31b8a bellard
    case TARGET_NR_oldolduname:
810 31e31b8a bellard
        goto unimplemented;
811 31e31b8a bellard
    case TARGET_NR_umask:
812 31e31b8a bellard
        ret = get_errno(umask(arg1));
813 31e31b8a bellard
        break;
814 31e31b8a bellard
    case TARGET_NR_chroot:
815 31e31b8a bellard
        ret = get_errno(chroot((const char *)arg1));
816 31e31b8a bellard
        break;
817 31e31b8a bellard
    case TARGET_NR_ustat:
818 31e31b8a bellard
        goto unimplemented;
819 31e31b8a bellard
    case TARGET_NR_dup2:
820 31e31b8a bellard
        ret = get_errno(dup2(arg1, arg2));
821 31e31b8a bellard
        break;
822 31e31b8a bellard
    case TARGET_NR_getppid:
823 31e31b8a bellard
        ret = get_errno(getppid());
824 31e31b8a bellard
        break;
825 31e31b8a bellard
    case TARGET_NR_getpgrp:
826 31e31b8a bellard
        ret = get_errno(getpgrp());
827 31e31b8a bellard
        break;
828 31e31b8a bellard
    case TARGET_NR_setsid:
829 31e31b8a bellard
        ret = get_errno(setsid());
830 31e31b8a bellard
        break;
831 31e31b8a bellard
    case TARGET_NR_sigaction:
832 31e31b8a bellard
#if 0
833 31e31b8a bellard
        {
834 31e31b8a bellard
            int signum = arg1;
835 31e31b8a bellard
            struct target_old_sigaction *tact = arg2, *toldact = arg3;
836 31e31b8a bellard
            ret = get_errno(setsid());
837 31e31b8a bellard
            
838 31e31b8a bellard

839 31e31b8a bellard
        }
840 31e31b8a bellard
        break;
841 31e31b8a bellard
#else
842 31e31b8a bellard
        goto unimplemented;
843 31e31b8a bellard
#endif
844 31e31b8a bellard
    case TARGET_NR_sgetmask:
845 31e31b8a bellard
        goto unimplemented;
846 31e31b8a bellard
    case TARGET_NR_ssetmask:
847 31e31b8a bellard
        goto unimplemented;
848 31e31b8a bellard
    case TARGET_NR_setreuid:
849 31e31b8a bellard
        ret = get_errno(setreuid(arg1, arg2));
850 31e31b8a bellard
        break;
851 31e31b8a bellard
    case TARGET_NR_setregid:
852 31e31b8a bellard
        ret = get_errno(setregid(arg1, arg2));
853 31e31b8a bellard
        break;
854 31e31b8a bellard
    case TARGET_NR_sigsuspend:
855 31e31b8a bellard
        goto unimplemented;
856 31e31b8a bellard
    case TARGET_NR_sigpending:
857 31e31b8a bellard
        goto unimplemented;
858 31e31b8a bellard
    case TARGET_NR_sethostname:
859 31e31b8a bellard
        ret = get_errno(sethostname((const char *)arg1, arg2));
860 31e31b8a bellard
        break;
861 31e31b8a bellard
    case TARGET_NR_setrlimit:
862 31e31b8a bellard
        goto unimplemented;
863 31e31b8a bellard
    case TARGET_NR_getrlimit:
864 31e31b8a bellard
        goto unimplemented;
865 31e31b8a bellard
    case TARGET_NR_getrusage:
866 31e31b8a bellard
        goto unimplemented;
867 31e31b8a bellard
    case TARGET_NR_gettimeofday:
868 31e31b8a bellard
        {
869 31e31b8a bellard
            struct target_timeval *target_tv = (void *)arg1;
870 31e31b8a bellard
            struct timeval tv;
871 31e31b8a bellard
            ret = get_errno(gettimeofday(&tv, NULL));
872 31e31b8a bellard
            if (!is_error(ret)) {
873 31e31b8a bellard
                target_tv->tv_sec = tswapl(tv.tv_sec);
874 31e31b8a bellard
                target_tv->tv_usec = tswapl(tv.tv_usec);
875 31e31b8a bellard
            }
876 31e31b8a bellard
        }
877 31e31b8a bellard
        break;
878 31e31b8a bellard
    case TARGET_NR_settimeofday:
879 31e31b8a bellard
        {
880 31e31b8a bellard
            struct target_timeval *target_tv = (void *)arg1;
881 31e31b8a bellard
            struct timeval tv;
882 31e31b8a bellard
            tv.tv_sec = tswapl(target_tv->tv_sec);
883 31e31b8a bellard
            tv.tv_usec = tswapl(target_tv->tv_usec);
884 31e31b8a bellard
            ret = get_errno(settimeofday(&tv, NULL));
885 31e31b8a bellard
        }
886 31e31b8a bellard
        break;
887 31e31b8a bellard
    case TARGET_NR_getgroups:
888 31e31b8a bellard
        goto unimplemented;
889 31e31b8a bellard
    case TARGET_NR_setgroups:
890 31e31b8a bellard
        goto unimplemented;
891 31e31b8a bellard
    case TARGET_NR_select:
892 31e31b8a bellard
        goto unimplemented;
893 31e31b8a bellard
    case TARGET_NR_symlink:
894 31e31b8a bellard
        ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
895 31e31b8a bellard
        break;
896 31e31b8a bellard
    case TARGET_NR_oldlstat:
897 31e31b8a bellard
        goto unimplemented;
898 31e31b8a bellard
    case TARGET_NR_readlink:
899 31e31b8a bellard
        ret = get_errno(readlink((const char *)arg1, (char *)arg2, arg3));
900 31e31b8a bellard
        break;
901 31e31b8a bellard
    case TARGET_NR_uselib:
902 31e31b8a bellard
        goto unimplemented;
903 31e31b8a bellard
    case TARGET_NR_swapon:
904 31e31b8a bellard
        ret = get_errno(swapon((const char *)arg1, arg2));
905 31e31b8a bellard
        break;
906 31e31b8a bellard
    case TARGET_NR_reboot:
907 31e31b8a bellard
        goto unimplemented;
908 31e31b8a bellard
    case TARGET_NR_readdir:
909 31e31b8a bellard
        goto unimplemented;
910 31e31b8a bellard
#ifdef TARGET_I386
911 31e31b8a bellard
    case TARGET_NR_mmap:
912 31e31b8a bellard
        {
913 31e31b8a bellard
            uint32_t v1, v2, v3, v4, v5, v6, *vptr;
914 31e31b8a bellard
            vptr = (uint32_t *)arg1;
915 31e31b8a bellard
            v1 = tswap32(vptr[0]);
916 31e31b8a bellard
            v2 = tswap32(vptr[1]);
917 31e31b8a bellard
            v3 = tswap32(vptr[2]);
918 31e31b8a bellard
            v4 = tswap32(vptr[3]);
919 31e31b8a bellard
            v5 = tswap32(vptr[4]);
920 31e31b8a bellard
            v6 = tswap32(vptr[5]);
921 31e31b8a bellard
            ret = get_errno((long)mmap((void *)v1, v2, v3, v4, v5, v6));
922 31e31b8a bellard
        }
923 31e31b8a bellard
        break;
924 31e31b8a bellard
#endif
925 31e31b8a bellard
#ifdef TARGET_I386
926 31e31b8a bellard
    case TARGET_NR_mmap2:
927 31e31b8a bellard
#else
928 31e31b8a bellard
    case TARGET_NR_mmap:
929 31e31b8a bellard
#endif
930 31e31b8a bellard
        ret = get_errno((long)mmap((void *)arg1, arg2, arg3, arg4, arg5, arg6));
931 31e31b8a bellard
        break;
932 31e31b8a bellard
    case TARGET_NR_munmap:
933 31e31b8a bellard
        ret = get_errno(munmap((void *)arg1, arg2));
934 31e31b8a bellard
        break;
935 31e31b8a bellard
    case TARGET_NR_truncate:
936 31e31b8a bellard
        ret = get_errno(truncate((const char *)arg1, arg2));
937 31e31b8a bellard
        break;
938 31e31b8a bellard
    case TARGET_NR_ftruncate:
939 31e31b8a bellard
        ret = get_errno(ftruncate(arg1, arg2));
940 31e31b8a bellard
        break;
941 31e31b8a bellard
    case TARGET_NR_fchmod:
942 31e31b8a bellard
        ret = get_errno(fchmod(arg1, arg2));
943 31e31b8a bellard
        break;
944 31e31b8a bellard
    case TARGET_NR_fchown:
945 31e31b8a bellard
        ret = get_errno(fchown(arg1, arg2, arg3));
946 31e31b8a bellard
        break;
947 31e31b8a bellard
    case TARGET_NR_getpriority:
948 31e31b8a bellard
        ret = get_errno(getpriority(arg1, arg2));
949 31e31b8a bellard
        break;
950 31e31b8a bellard
    case TARGET_NR_setpriority:
951 31e31b8a bellard
        ret = get_errno(setpriority(arg1, arg2, arg3));
952 31e31b8a bellard
        break;
953 31e31b8a bellard
    case TARGET_NR_profil:
954 31e31b8a bellard
        goto unimplemented;
955 31e31b8a bellard
    case TARGET_NR_statfs:
956 31e31b8a bellard
        stfs = (void *)arg2;
957 31e31b8a bellard
        ret = get_errno(sys_statfs((const char *)arg1, stfs));
958 31e31b8a bellard
    convert_statfs:
959 31e31b8a bellard
        if (!is_error(ret)) {
960 31e31b8a bellard
            tswap32s(&stfs->f_type);
961 31e31b8a bellard
            tswap32s(&stfs->f_bsize);
962 31e31b8a bellard
            tswap32s(&stfs->f_blocks);
963 31e31b8a bellard
            tswap32s(&stfs->f_bfree);
964 31e31b8a bellard
            tswap32s(&stfs->f_bavail);
965 31e31b8a bellard
            tswap32s(&stfs->f_files);
966 31e31b8a bellard
            tswap32s(&stfs->f_ffree);
967 31e31b8a bellard
            tswap32s(&stfs->f_fsid.val[0]);
968 31e31b8a bellard
            tswap32s(&stfs->f_fsid.val[1]);
969 31e31b8a bellard
            tswap32s(&stfs->f_namelen);
970 31e31b8a bellard
        }
971 31e31b8a bellard
        break;
972 31e31b8a bellard
    case TARGET_NR_fstatfs:
973 31e31b8a bellard
        stfs = (void *)arg2;
974 31e31b8a bellard
        ret = get_errno(sys_fstatfs(arg1, stfs));
975 31e31b8a bellard
        goto convert_statfs;
976 31e31b8a bellard
    case TARGET_NR_ioperm:
977 31e31b8a bellard
        goto unimplemented;
978 31e31b8a bellard
    case TARGET_NR_socketcall:
979 31e31b8a bellard
        ret = do_socketcall(arg1, (long *)arg2);
980 31e31b8a bellard
        break;
981 31e31b8a bellard
    case TARGET_NR_syslog:
982 31e31b8a bellard
        goto unimplemented;
983 31e31b8a bellard
    case TARGET_NR_setitimer:
984 31e31b8a bellard
        goto unimplemented;
985 31e31b8a bellard
    case TARGET_NR_getitimer:
986 31e31b8a bellard
        goto unimplemented;
987 31e31b8a bellard
    case TARGET_NR_stat:
988 31e31b8a bellard
        ret = get_errno(stat((const char *)arg1, &st));
989 31e31b8a bellard
        goto do_stat;
990 31e31b8a bellard
    case TARGET_NR_lstat:
991 31e31b8a bellard
        ret = get_errno(lstat((const char *)arg1, &st));
992 31e31b8a bellard
        goto do_stat;
993 31e31b8a bellard
    case TARGET_NR_fstat:
994 31e31b8a bellard
        {
995 31e31b8a bellard
            ret = get_errno(fstat(arg1, &st));
996 31e31b8a bellard
        do_stat:
997 31e31b8a bellard
            if (!is_error(ret)) {
998 31e31b8a bellard
                struct target_stat *target_st = (void *)arg2;
999 31e31b8a bellard
                target_st->st_dev = tswap16(st.st_dev);
1000 31e31b8a bellard
                target_st->st_ino = tswapl(st.st_ino);
1001 31e31b8a bellard
                target_st->st_mode = tswap16(st.st_mode);
1002 31e31b8a bellard
                target_st->st_nlink = tswap16(st.st_nlink);
1003 31e31b8a bellard
                target_st->st_uid = tswap16(st.st_uid);
1004 31e31b8a bellard
                target_st->st_gid = tswap16(st.st_gid);
1005 31e31b8a bellard
                target_st->st_rdev = tswap16(st.st_rdev);
1006 31e31b8a bellard
                target_st->st_size = tswapl(st.st_size);
1007 31e31b8a bellard
                target_st->st_blksize = tswapl(st.st_blksize);
1008 31e31b8a bellard
                target_st->st_blocks = tswapl(st.st_blocks);
1009 31e31b8a bellard
                target_st->st_atime = tswapl(st.st_atime);
1010 31e31b8a bellard
                target_st->st_mtime = tswapl(st.st_mtime);
1011 31e31b8a bellard
                target_st->st_ctime = tswapl(st.st_ctime);
1012 31e31b8a bellard
            }
1013 31e31b8a bellard
        }
1014 31e31b8a bellard
        break;
1015 31e31b8a bellard
    case TARGET_NR_olduname:
1016 31e31b8a bellard
        goto unimplemented;
1017 31e31b8a bellard
    case TARGET_NR_iopl:
1018 31e31b8a bellard
        goto unimplemented;
1019 31e31b8a bellard
    case TARGET_NR_vhangup:
1020 31e31b8a bellard
        ret = get_errno(vhangup());
1021 31e31b8a bellard
        break;
1022 31e31b8a bellard
    case TARGET_NR_idle:
1023 31e31b8a bellard
        goto unimplemented;
1024 31e31b8a bellard
    case TARGET_NR_vm86old:
1025 31e31b8a bellard
        goto unimplemented;
1026 31e31b8a bellard
    case TARGET_NR_wait4:
1027 31e31b8a bellard
        {
1028 31e31b8a bellard
            int status;
1029 31e31b8a bellard
            target_long *status_ptr = (void *)arg2;
1030 31e31b8a bellard
            struct rusage rusage, *rusage_ptr;
1031 31e31b8a bellard
            struct target_rusage *target_rusage = (void *)arg4;
1032 31e31b8a bellard
            if (target_rusage)
1033 31e31b8a bellard
                rusage_ptr = &rusage;
1034 31e31b8a bellard
            else
1035 31e31b8a bellard
                rusage_ptr = NULL;
1036 31e31b8a bellard
            ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
1037 31e31b8a bellard
            if (!is_error(ret)) {
1038 31e31b8a bellard
                if (status_ptr)
1039 31e31b8a bellard
                    *status_ptr = tswap32(status);
1040 31e31b8a bellard
                if (target_rusage) {
1041 31e31b8a bellard
                    target_rusage->ru_utime.tv_sec = tswapl(rusage.ru_utime.tv_sec);
1042 31e31b8a bellard
                    target_rusage->ru_utime.tv_usec = tswapl(rusage.ru_utime.tv_usec);
1043 31e31b8a bellard
                    target_rusage->ru_stime.tv_sec = tswapl(rusage.ru_stime.tv_sec);
1044 31e31b8a bellard
                    target_rusage->ru_stime.tv_usec = tswapl(rusage.ru_stime.tv_usec);
1045 31e31b8a bellard
                    target_rusage->ru_maxrss = tswapl(rusage.ru_maxrss);
1046 31e31b8a bellard
                    target_rusage->ru_ixrss = tswapl(rusage.ru_ixrss);
1047 31e31b8a bellard
                    target_rusage->ru_idrss = tswapl(rusage.ru_idrss);
1048 31e31b8a bellard
                    target_rusage->ru_isrss = tswapl(rusage.ru_isrss);
1049 31e31b8a bellard
                    target_rusage->ru_minflt = tswapl(rusage.ru_minflt);
1050 31e31b8a bellard
                    target_rusage->ru_majflt = tswapl(rusage.ru_majflt);
1051 31e31b8a bellard
                    target_rusage->ru_nswap = tswapl(rusage.ru_nswap);
1052 31e31b8a bellard
                    target_rusage->ru_inblock = tswapl(rusage.ru_inblock);
1053 31e31b8a bellard
                    target_rusage->ru_oublock = tswapl(rusage.ru_oublock);
1054 31e31b8a bellard
                    target_rusage->ru_msgsnd = tswapl(rusage.ru_msgsnd);
1055 31e31b8a bellard
                    target_rusage->ru_msgrcv = tswapl(rusage.ru_msgrcv);
1056 31e31b8a bellard
                    target_rusage->ru_nsignals = tswapl(rusage.ru_nsignals);
1057 31e31b8a bellard
                    target_rusage->ru_nvcsw = tswapl(rusage.ru_nvcsw);
1058 31e31b8a bellard
                    target_rusage->ru_nivcsw = tswapl(rusage.ru_nivcsw);
1059 31e31b8a bellard
                }
1060 31e31b8a bellard
            }
1061 31e31b8a bellard
        }
1062 31e31b8a bellard
        break;
1063 31e31b8a bellard
    case TARGET_NR_swapoff:
1064 31e31b8a bellard
        ret = get_errno(swapoff((const char *)arg1));
1065 31e31b8a bellard
        break;
1066 31e31b8a bellard
    case TARGET_NR_sysinfo:
1067 31e31b8a bellard
        goto unimplemented;
1068 31e31b8a bellard
    case TARGET_NR_ipc:
1069 31e31b8a bellard
        goto unimplemented;
1070 31e31b8a bellard
    case TARGET_NR_fsync:
1071 31e31b8a bellard
        ret = get_errno(fsync(arg1));
1072 31e31b8a bellard
        break;
1073 31e31b8a bellard
    case TARGET_NR_sigreturn:
1074 31e31b8a bellard
        goto unimplemented;
1075 31e31b8a bellard
    case TARGET_NR_clone:
1076 31e31b8a bellard
        goto unimplemented;
1077 31e31b8a bellard
    case TARGET_NR_setdomainname:
1078 31e31b8a bellard
        ret = get_errno(setdomainname((const char *)arg1, arg2));
1079 31e31b8a bellard
        break;
1080 31e31b8a bellard
    case TARGET_NR_uname:
1081 31e31b8a bellard
        /* no need to transcode because we use the linux syscall */
1082 31e31b8a bellard
        ret = get_errno(sys_uname((struct new_utsname *)arg1));
1083 31e31b8a bellard
        break;
1084 31e31b8a bellard
    case TARGET_NR_modify_ldt:
1085 31e31b8a bellard
        goto unimplemented;
1086 31e31b8a bellard
    case TARGET_NR_adjtimex:
1087 31e31b8a bellard
        goto unimplemented;
1088 31e31b8a bellard
    case TARGET_NR_mprotect:
1089 31e31b8a bellard
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1090 31e31b8a bellard
        break;
1091 31e31b8a bellard
    case TARGET_NR_sigprocmask:
1092 31e31b8a bellard
        {
1093 31e31b8a bellard
            int how = arg1;
1094 31e31b8a bellard
            sigset_t set, oldset, *set_ptr;
1095 31e31b8a bellard
            target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
1096 31e31b8a bellard
            
1097 31e31b8a bellard
            switch(how) {
1098 31e31b8a bellard
            case TARGET_SIG_BLOCK:
1099 31e31b8a bellard
                how = SIG_BLOCK;
1100 31e31b8a bellard
                break;
1101 31e31b8a bellard
            case TARGET_SIG_UNBLOCK:
1102 31e31b8a bellard
                how = SIG_UNBLOCK;
1103 31e31b8a bellard
                break;
1104 31e31b8a bellard
            case TARGET_SIG_SETMASK:
1105 31e31b8a bellard
                how = SIG_SETMASK;
1106 31e31b8a bellard
                break;
1107 31e31b8a bellard
            default:
1108 31e31b8a bellard
                ret = -EINVAL;
1109 31e31b8a bellard
                goto fail;
1110 31e31b8a bellard
            }
1111 31e31b8a bellard
            
1112 31e31b8a bellard
            if (pset) {
1113 31e31b8a bellard
                target_to_host_old_sigset(&set, pset);
1114 31e31b8a bellard
                set_ptr = &set;
1115 31e31b8a bellard
            } else {
1116 31e31b8a bellard
                set_ptr = NULL;
1117 31e31b8a bellard
            }
1118 31e31b8a bellard
            ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
1119 31e31b8a bellard
            if (!is_error(ret) && poldset) {
1120 31e31b8a bellard
                host_to_target_old_sigset(poldset, &oldset);
1121 31e31b8a bellard
            }
1122 31e31b8a bellard
        }
1123 31e31b8a bellard
        break;
1124 31e31b8a bellard
    case TARGET_NR_create_module:
1125 31e31b8a bellard
    case TARGET_NR_init_module:
1126 31e31b8a bellard
    case TARGET_NR_delete_module:
1127 31e31b8a bellard
    case TARGET_NR_get_kernel_syms:
1128 31e31b8a bellard
        goto unimplemented;
1129 31e31b8a bellard
    case TARGET_NR_quotactl:
1130 31e31b8a bellard
        goto unimplemented;
1131 31e31b8a bellard
    case TARGET_NR_getpgid:
1132 31e31b8a bellard
        ret = get_errno(getpgid(arg1));
1133 31e31b8a bellard
        break;
1134 31e31b8a bellard
    case TARGET_NR_fchdir:
1135 31e31b8a bellard
        ret = get_errno(fchdir(arg1));
1136 31e31b8a bellard
        break;
1137 31e31b8a bellard
    case TARGET_NR_bdflush:
1138 31e31b8a bellard
        goto unimplemented;
1139 31e31b8a bellard
    case TARGET_NR_sysfs:
1140 31e31b8a bellard
        goto unimplemented;
1141 31e31b8a bellard
    case TARGET_NR_personality:
1142 31e31b8a bellard
        ret = get_errno(mprotect((void *)arg1, arg2, arg3));
1143 31e31b8a bellard
        break;
1144 31e31b8a bellard
    case TARGET_NR_afs_syscall:
1145 31e31b8a bellard
        goto unimplemented;
1146 31e31b8a bellard
    case TARGET_NR_setfsuid:
1147 31e31b8a bellard
        goto unimplemented;
1148 31e31b8a bellard
    case TARGET_NR_setfsgid:
1149 31e31b8a bellard
        goto unimplemented;
1150 31e31b8a bellard
    case TARGET_NR__llseek:
1151 31e31b8a bellard
        {
1152 31e31b8a bellard
            int64_t res;
1153 31e31b8a bellard
            ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
1154 31e31b8a bellard
            *(int64_t *)arg4 = tswap64(res);
1155 31e31b8a bellard
        }
1156 31e31b8a bellard
        break;
1157 31e31b8a bellard
    case TARGET_NR_getdents:
1158 31e31b8a bellard
#if TARGET_LONG_SIZE != 4
1159 31e31b8a bellard
#error not supported
1160 31e31b8a bellard
#endif
1161 31e31b8a bellard
        {
1162 31e31b8a bellard
            struct dirent *dirp = (void *)arg2;
1163 31e31b8a bellard
            long count = arg3;
1164 31e31b8a bellard
            ret = get_errno(getdents(arg1, dirp, count));
1165 31e31b8a bellard
            if (!is_error(ret)) {
1166 31e31b8a bellard
                struct dirent *de;
1167 31e31b8a bellard
                int len = ret;
1168 31e31b8a bellard
                int reclen;
1169 31e31b8a bellard
                de = dirp;
1170 31e31b8a bellard
                while (len > 0) {
1171 31e31b8a bellard
                    reclen = tswap16(de->d_reclen);
1172 31e31b8a bellard
                    if (reclen > len)
1173 31e31b8a bellard
                        break;
1174 31e31b8a bellard
                    de->d_reclen = reclen;
1175 31e31b8a bellard
                    tswapls(&de->d_ino);
1176 31e31b8a bellard
                    tswapls(&de->d_off);
1177 31e31b8a bellard
                    de = (struct dirent *)((char *)de + reclen);
1178 31e31b8a bellard
                    len -= reclen;
1179 31e31b8a bellard
                }
1180 31e31b8a bellard
            }
1181 31e31b8a bellard
        }
1182 31e31b8a bellard
        break;
1183 31e31b8a bellard
    case TARGET_NR__newselect:
1184 31e31b8a bellard
        ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 
1185 31e31b8a bellard
                        (void *)arg5);
1186 31e31b8a bellard
        break;
1187 31e31b8a bellard
    case TARGET_NR_flock:
1188 31e31b8a bellard
        goto unimplemented;
1189 31e31b8a bellard
    case TARGET_NR_msync:
1190 31e31b8a bellard
        ret = get_errno(msync((void *)arg1, arg2, arg3));
1191 31e31b8a bellard
        break;
1192 31e31b8a bellard
    case TARGET_NR_readv:
1193 31e31b8a bellard
        {
1194 31e31b8a bellard
            int count = arg3;
1195 31e31b8a bellard
            int i;
1196 31e31b8a bellard
            struct iovec *vec;
1197 31e31b8a bellard
            struct target_iovec *target_vec = (void *)arg2;
1198 31e31b8a bellard
1199 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
1200 31e31b8a bellard
            for(i = 0;i < count; i++) {
1201 31e31b8a bellard
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1202 31e31b8a bellard
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1203 31e31b8a bellard
            }
1204 31e31b8a bellard
            ret = get_errno(readv(arg1, vec, count));
1205 31e31b8a bellard
        }
1206 31e31b8a bellard
        break;
1207 31e31b8a bellard
    case TARGET_NR_writev:
1208 31e31b8a bellard
        {
1209 31e31b8a bellard
            int count = arg3;
1210 31e31b8a bellard
            int i;
1211 31e31b8a bellard
            struct iovec *vec;
1212 31e31b8a bellard
            struct target_iovec *target_vec = (void *)arg2;
1213 31e31b8a bellard
1214 31e31b8a bellard
            vec = alloca(count * sizeof(struct iovec));
1215 31e31b8a bellard
            for(i = 0;i < count; i++) {
1216 31e31b8a bellard
                vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
1217 31e31b8a bellard
                vec[i].iov_len = tswapl(target_vec[i].iov_len);
1218 31e31b8a bellard
            }
1219 31e31b8a bellard
            ret = get_errno(writev(arg1, vec, count));
1220 31e31b8a bellard
        }
1221 31e31b8a bellard
        break;
1222 31e31b8a bellard
    case TARGET_NR_getsid:
1223 31e31b8a bellard
        ret = get_errno(getsid(arg1));
1224 31e31b8a bellard
        break;
1225 31e31b8a bellard
    case TARGET_NR_fdatasync:
1226 31e31b8a bellard
        goto unimplemented;
1227 31e31b8a bellard
    case TARGET_NR__sysctl:
1228 31e31b8a bellard
        goto unimplemented;
1229 31e31b8a bellard
    case TARGET_NR_mlock:
1230 31e31b8a bellard
        ret = get_errno(mlock((void *)arg1, arg2));
1231 31e31b8a bellard
        break;
1232 31e31b8a bellard
    case TARGET_NR_munlock:
1233 31e31b8a bellard
        ret = get_errno(munlock((void *)arg1, arg2));
1234 31e31b8a bellard
        break;
1235 31e31b8a bellard
    case TARGET_NR_mlockall:
1236 31e31b8a bellard
        ret = get_errno(mlockall(arg1));
1237 31e31b8a bellard
        break;
1238 31e31b8a bellard
    case TARGET_NR_munlockall:
1239 31e31b8a bellard
        ret = get_errno(munlockall());
1240 31e31b8a bellard
        break;
1241 31e31b8a bellard
    case TARGET_NR_sched_setparam:
1242 31e31b8a bellard
        goto unimplemented;
1243 31e31b8a bellard
    case TARGET_NR_sched_getparam:
1244 31e31b8a bellard
        goto unimplemented;
1245 31e31b8a bellard
    case TARGET_NR_sched_setscheduler:
1246 31e31b8a bellard
        goto unimplemented;
1247 31e31b8a bellard
    case TARGET_NR_sched_getscheduler:
1248 31e31b8a bellard
        goto unimplemented;
1249 31e31b8a bellard
    case TARGET_NR_sched_yield:
1250 31e31b8a bellard
        ret = get_errno(sched_yield());
1251 31e31b8a bellard
        break;
1252 31e31b8a bellard
    case TARGET_NR_sched_get_priority_max:
1253 31e31b8a bellard
    case TARGET_NR_sched_get_priority_min:
1254 31e31b8a bellard
    case TARGET_NR_sched_rr_get_interval:
1255 31e31b8a bellard
    case TARGET_NR_nanosleep:
1256 31e31b8a bellard
    case TARGET_NR_mremap:
1257 31e31b8a bellard
    case TARGET_NR_setresuid:
1258 31e31b8a bellard
    case TARGET_NR_getresuid:
1259 31e31b8a bellard
    case TARGET_NR_vm86:
1260 31e31b8a bellard
    case TARGET_NR_query_module:
1261 31e31b8a bellard
    case TARGET_NR_poll:
1262 31e31b8a bellard
    case TARGET_NR_nfsservctl:
1263 31e31b8a bellard
    case TARGET_NR_setresgid:
1264 31e31b8a bellard
    case TARGET_NR_getresgid:
1265 31e31b8a bellard
    case TARGET_NR_prctl:
1266 31e31b8a bellard
    case TARGET_NR_rt_sigreturn:
1267 31e31b8a bellard
    case TARGET_NR_rt_sigaction:
1268 31e31b8a bellard
    case TARGET_NR_rt_sigprocmask:
1269 31e31b8a bellard
    case TARGET_NR_rt_sigpending:
1270 31e31b8a bellard
    case TARGET_NR_rt_sigtimedwait:
1271 31e31b8a bellard
    case TARGET_NR_rt_sigqueueinfo:
1272 31e31b8a bellard
    case TARGET_NR_rt_sigsuspend:
1273 31e31b8a bellard
    case TARGET_NR_pread:
1274 31e31b8a bellard
    case TARGET_NR_pwrite:
1275 31e31b8a bellard
        goto unimplemented;
1276 31e31b8a bellard
    case TARGET_NR_chown:
1277 31e31b8a bellard
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
1278 31e31b8a bellard
        break;
1279 31e31b8a bellard
    case TARGET_NR_getcwd:
1280 31e31b8a bellard
        ret = get_errno(sys_getcwd((char *)arg1, arg2));
1281 31e31b8a bellard
        break;
1282 31e31b8a bellard
    case TARGET_NR_capget:
1283 31e31b8a bellard
    case TARGET_NR_capset:
1284 31e31b8a bellard
    case TARGET_NR_sigaltstack:
1285 31e31b8a bellard
    case TARGET_NR_sendfile:
1286 31e31b8a bellard
    case TARGET_NR_getpmsg:
1287 31e31b8a bellard
    case TARGET_NR_putpmsg:
1288 31e31b8a bellard
    case TARGET_NR_vfork:
1289 31e31b8a bellard
        ret = get_errno(vfork());
1290 31e31b8a bellard
        break;
1291 31e31b8a bellard
    case TARGET_NR_ugetrlimit:
1292 31e31b8a bellard
    case TARGET_NR_truncate64:
1293 31e31b8a bellard
    case TARGET_NR_ftruncate64:
1294 31e31b8a bellard
    case TARGET_NR_stat64:
1295 31e31b8a bellard
    case TARGET_NR_lstat64:
1296 31e31b8a bellard
    case TARGET_NR_fstat64:
1297 31e31b8a bellard
    case TARGET_NR_lchown32:
1298 31e31b8a bellard
    case TARGET_NR_getuid32:
1299 31e31b8a bellard
    case TARGET_NR_getgid32:
1300 31e31b8a bellard
    case TARGET_NR_geteuid32:
1301 31e31b8a bellard
    case TARGET_NR_getegid32:
1302 31e31b8a bellard
    case TARGET_NR_setreuid32:
1303 31e31b8a bellard
    case TARGET_NR_setregid32:
1304 31e31b8a bellard
    case TARGET_NR_getgroups32:
1305 31e31b8a bellard
    case TARGET_NR_setgroups32:
1306 31e31b8a bellard
    case TARGET_NR_fchown32:
1307 31e31b8a bellard
    case TARGET_NR_setresuid32:
1308 31e31b8a bellard
    case TARGET_NR_getresuid32:
1309 31e31b8a bellard
    case TARGET_NR_setresgid32:
1310 31e31b8a bellard
    case TARGET_NR_getresgid32:
1311 31e31b8a bellard
    case TARGET_NR_chown32:
1312 31e31b8a bellard
    case TARGET_NR_setuid32:
1313 31e31b8a bellard
    case TARGET_NR_setgid32:
1314 31e31b8a bellard
    case TARGET_NR_setfsuid32:
1315 31e31b8a bellard
    case TARGET_NR_setfsgid32:
1316 31e31b8a bellard
    case TARGET_NR_pivot_root:
1317 31e31b8a bellard
    case TARGET_NR_mincore:
1318 31e31b8a bellard
    case TARGET_NR_madvise:
1319 31e31b8a bellard
    case TARGET_NR_getdents64:
1320 31e31b8a bellard
    case TARGET_NR_fcntl64:
1321 31e31b8a bellard
    case TARGET_NR_security:
1322 31e31b8a bellard
        goto unimplemented;
1323 31e31b8a bellard
    case TARGET_NR_gettid:
1324 31e31b8a bellard
        ret = get_errno(gettid());
1325 31e31b8a bellard
        break;
1326 31e31b8a bellard
    case TARGET_NR_readahead:
1327 31e31b8a bellard
    case TARGET_NR_setxattr:
1328 31e31b8a bellard
    case TARGET_NR_lsetxattr:
1329 31e31b8a bellard
    case TARGET_NR_fsetxattr:
1330 31e31b8a bellard
    case TARGET_NR_getxattr:
1331 31e31b8a bellard
    case TARGET_NR_lgetxattr:
1332 31e31b8a bellard
    case TARGET_NR_fgetxattr:
1333 31e31b8a bellard
    case TARGET_NR_listxattr:
1334 31e31b8a bellard
    case TARGET_NR_llistxattr:
1335 31e31b8a bellard
    case TARGET_NR_flistxattr:
1336 31e31b8a bellard
    case TARGET_NR_removexattr:
1337 31e31b8a bellard
    case TARGET_NR_lremovexattr:
1338 31e31b8a bellard
    case TARGET_NR_fremovexattr:
1339 31e31b8a bellard
        goto unimplemented;
1340 31e31b8a bellard
    default:
1341 31e31b8a bellard
    unimplemented:
1342 31e31b8a bellard
        gemu_log("Unsupported syscall: %d\n", num);
1343 31e31b8a bellard
        ret = -ENOSYS;
1344 31e31b8a bellard
        break;
1345 31e31b8a bellard
    }
1346 31e31b8a bellard
 fail:
1347 31e31b8a bellard
    return ret;
1348 31e31b8a bellard
}