]>
Commit | Line | Data |
---|---|---|
c5c84d16 WL |
1 | /* |
2 | * file related system call shims and definitions | |
3 | * | |
4 | * Copyright (c) 2013 Stacey D. Son | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
9c092804 MA |
20 | #ifndef BSD_FILE_H |
21 | #define BSD_FILE_H | |
c5c84d16 WL |
22 | |
23 | #include "qemu/path.h" | |
24 | ||
25 | extern struct iovec *lock_iovec(int type, abi_ulong target_addr, int count, | |
26 | int copy); | |
27 | extern void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, | |
28 | int copy); | |
29 | ||
80da1b00 WL |
30 | ssize_t safe_read(int fd, void *buf, size_t nbytes); |
31 | ssize_t safe_pread(int fd, void *buf, size_t nbytes, off_t offset); | |
32 | ssize_t safe_readv(int fd, const struct iovec *iov, int iovcnt); | |
33 | ssize_t safe_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); | |
34 | ||
35 | /* read(2) */ | |
36 | static abi_long do_bsd_read(abi_long arg1, abi_long arg2, abi_long arg3) | |
37 | { | |
38 | abi_long ret; | |
39 | void *p; | |
40 | ||
41 | p = lock_user(VERIFY_WRITE, arg2, arg3, 0); | |
42 | if (p == NULL) { | |
43 | return -TARGET_EFAULT; | |
44 | } | |
45 | ret = get_errno(safe_read(arg1, p, arg3)); | |
46 | unlock_user(p, arg2, ret); | |
47 | ||
48 | return ret; | |
49 | } | |
50 | ||
51 | /* pread(2) */ | |
52 | static abi_long do_bsd_pread(void *cpu_env, abi_long arg1, | |
53 | abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) | |
54 | { | |
55 | abi_long ret; | |
56 | void *p; | |
57 | ||
58 | p = lock_user(VERIFY_WRITE, arg2, arg3, 0); | |
59 | if (p == NULL) { | |
60 | return -TARGET_EFAULT; | |
61 | } | |
62 | if (regpairs_aligned(cpu_env) != 0) { | |
63 | arg4 = arg5; | |
64 | arg5 = arg6; | |
65 | } | |
66 | ret = get_errno(safe_pread(arg1, p, arg3, target_arg64(arg4, arg5))); | |
67 | unlock_user(p, arg2, ret); | |
68 | ||
69 | return ret; | |
70 | } | |
71 | ||
72 | /* readv(2) */ | |
73 | static abi_long do_bsd_readv(abi_long arg1, abi_long arg2, abi_long arg3) | |
74 | { | |
75 | abi_long ret; | |
76 | struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); | |
77 | ||
78 | if (vec != NULL) { | |
79 | ret = get_errno(safe_readv(arg1, vec, arg3)); | |
80 | unlock_iovec(vec, arg2, arg3, 1); | |
81 | } else { | |
82 | ret = -host_to_target_errno(errno); | |
83 | } | |
84 | ||
85 | return ret; | |
86 | } | |
87 | ||
88 | /* preadv(2) */ | |
89 | static abi_long do_bsd_preadv(void *cpu_env, abi_long arg1, | |
90 | abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) | |
91 | { | |
92 | abi_long ret; | |
93 | struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 1); | |
94 | ||
95 | if (vec != NULL) { | |
96 | if (regpairs_aligned(cpu_env) != 0) { | |
97 | arg4 = arg5; | |
98 | arg5 = arg6; | |
99 | } | |
100 | ret = get_errno(safe_preadv(arg1, vec, arg3, target_arg64(arg4, arg5))); | |
101 | unlock_iovec(vec, arg2, arg3, 0); | |
102 | } else { | |
103 | ret = -host_to_target_errno(errno); | |
104 | } | |
105 | ||
106 | return ret; | |
107 | } | |
108 | ||
9c092804 | 109 | #endif /* BSD_FILE_H */ |