Skip to main content

shadow_rs/host/syscall/handler/
file.rs

1use linux_api::errno::Errno;
2use linux_api::posix_types::kernel_mode_t;
3use shadow_shim_helper_rs::syscall_types::ForeignPtr;
4
5use crate::cshadow;
6use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
7use crate::host::syscall::type_formatting::SyscallStringArg;
8use crate::host::syscall::types::{SyscallError, SyscallResult};
9
10impl SyscallHandler {
11    log_syscall!(
12        open,
13        /* rv */ std::ffi::c_int,
14        /* pathname */ SyscallStringArg,
15        /* flags */ linux_api::fcntl::OFlag,
16        /* mode */ nix::sys::stat::Mode,
17    );
18    pub fn open(
19        ctx: &mut SyscallContext,
20        _path: ForeignPtr<()>,
21        _flags: std::ffi::c_int,
22        _mode: kernel_mode_t,
23    ) -> SyscallResult {
24        Self::legacy_syscall(cshadow::syscallhandler_open, ctx)
25    }
26
27    log_syscall!(
28        creat,
29        /* rv */ std::ffi::c_int,
30        /* pathname */ SyscallStringArg,
31        /* mode */ nix::sys::stat::Mode
32    );
33    pub fn creat(ctx: &mut SyscallContext) -> SyscallResult {
34        Self::legacy_syscall(cshadow::syscallhandler_creat, ctx)
35    }
36
37    log_syscall!(
38        fadvise64,
39        /* rv */ std::ffi::c_int,
40        /* fd */ std::ffi::c_int,
41        /* offset */ linux_api::types::loff_t,
42        /* len */ linux_api::types::size_t,
43        /* advice */ std::ffi::c_int
44    );
45    pub fn fadvise64(ctx: &mut SyscallContext) -> SyscallResult {
46        Self::legacy_syscall(cshadow::syscallhandler_fadvise64, ctx)
47    }
48
49    log_syscall!(
50        fallocate,
51        /* rv */ std::ffi::c_int,
52        /* fd */ std::ffi::c_int,
53        /* mode */ std::ffi::c_int,
54        /* offset */ linux_api::types::loff_t,
55        /* len */ linux_api::types::loff_t
56    );
57    pub fn fallocate(ctx: &mut SyscallContext) -> SyscallResult {
58        Self::legacy_syscall(cshadow::syscallhandler_fallocate, ctx)
59    }
60
61    log_syscall!(
62        fchmod,
63        /* rv */ std::ffi::c_int,
64        /* fd */ std::ffi::c_int,
65        /* mode */ linux_api::types::umode_t,
66    );
67    pub fn fchmod(ctx: &mut SyscallContext) -> SyscallResult {
68        Self::legacy_syscall(cshadow::syscallhandler_fchmod, ctx)
69    }
70
71    log_syscall!(
72        fchown,
73        /* rv */ std::ffi::c_int,
74        /* fd */ std::ffi::c_uint,
75        /* user */ linux_api::types::uid_t,
76        /* group */ linux_api::types::gid_t
77    );
78    pub fn fchown(ctx: &mut SyscallContext) -> SyscallResult {
79        Self::legacy_syscall(cshadow::syscallhandler_fchown, ctx)
80    }
81
82    log_syscall!(
83        fdatasync,
84        /* rv */ std::ffi::c_int,
85        /* fd */ std::ffi::c_uint
86    );
87    pub fn fdatasync(ctx: &mut SyscallContext) -> SyscallResult {
88        Self::legacy_syscall(cshadow::syscallhandler_fdatasync, ctx)
89    }
90
91    log_syscall!(
92        fgetxattr,
93        /* rv */ std::ffi::c_int,
94        /* fd */ std::ffi::c_int,
95        /* name */ SyscallStringArg,
96        /* value */ *const std::ffi::c_void,
97        /* size */ linux_api::types::size_t
98    );
99    pub fn fgetxattr(ctx: &mut SyscallContext) -> SyscallResult {
100        Self::legacy_syscall(cshadow::syscallhandler_fgetxattr, ctx)
101    }
102
103    log_syscall!(
104        flistxattr,
105        /* rv */ std::ffi::c_int,
106        /* fd */ std::ffi::c_int,
107        /* This is actually a *list* of strings: "The list is the set of
108         * (null-terminated) names, one after the other."
109         * TODO: log the whole list instead of just the first element */
110        /* list */
111        SyscallStringArg,
112        /* size */ linux_api::types::size_t
113    );
114    pub fn flistxattr(ctx: &mut SyscallContext) -> SyscallResult {
115        Self::legacy_syscall(cshadow::syscallhandler_flistxattr, ctx)
116    }
117
118    log_syscall!(
119        flock,
120        /* rv */ std::ffi::c_int,
121        /* fd */ std::ffi::c_uint,
122        /* cmd */ std::ffi::c_uint
123    );
124    pub fn flock(ctx: &mut SyscallContext) -> SyscallResult {
125        warn_once_then_debug!(
126            "Using flock implementation that assumes no lock contention. \
127            See https://github.com/shadow/shadow/issues/2258"
128        );
129        Self::legacy_syscall(cshadow::syscallhandler_flock, ctx)
130    }
131
132    log_syscall!(
133        fremovexattr,
134        /* rv */ std::ffi::c_int,
135        /* fd */ std::ffi::c_int,
136        /* name */ SyscallStringArg
137    );
138    pub fn fremovexattr(ctx: &mut SyscallContext) -> SyscallResult {
139        Self::legacy_syscall(cshadow::syscallhandler_fremovexattr, ctx)
140    }
141
142    log_syscall!(
143        fsetxattr,
144        /* rv */ std::ffi::c_int,
145        /* fd */ std::ffi::c_int,
146        /* name */ SyscallStringArg,
147        /* value */ *const std::ffi::c_void,
148        /* size */ linux_api::types::size_t,
149        /* flags */ std::ffi::c_int
150    );
151    pub fn fsetxattr(ctx: &mut SyscallContext) -> SyscallResult {
152        Self::legacy_syscall(cshadow::syscallhandler_fsetxattr, ctx)
153    }
154
155    log_syscall!(
156        fsync,
157        /* rv */ std::ffi::c_int,
158        /* fd */ std::ffi::c_uint
159    );
160    pub fn fsync(ctx: &mut SyscallContext) -> SyscallResult {
161        Self::legacy_syscall(cshadow::syscallhandler_fsync, ctx)
162    }
163
164    log_syscall!(
165        ftruncate,
166        /* rv */ std::ffi::c_int,
167        /* fd */ std::ffi::c_uint,
168        /* length */ linux_api::types::off_t
169    );
170    pub fn ftruncate(ctx: &mut SyscallContext) -> SyscallResult {
171        Self::legacy_syscall(cshadow::syscallhandler_ftruncate, ctx)
172    }
173
174    log_syscall!(
175        getdents,
176        /* rv */ std::ffi::c_int,
177        /* fd */ std::ffi::c_uint,
178        /* dirent */ *const std::ffi::c_void,
179        /* count */ std::ffi::c_uint
180    );
181    pub fn getdents(ctx: &mut SyscallContext) -> SyscallResult {
182        Self::legacy_syscall(cshadow::syscallhandler_getdents, ctx)
183    }
184
185    log_syscall!(
186        getdents64,
187        /* rv */ std::ffi::c_int,
188        /* fd */ std::ffi::c_uint,
189        /* dirent */ *const std::ffi::c_void,
190        /* count */ std::ffi::c_uint
191    );
192    pub fn getdents64(ctx: &mut SyscallContext) -> SyscallResult {
193        Self::legacy_syscall(cshadow::syscallhandler_getdents64, ctx)
194    }
195
196    log_syscall!(
197        lseek,
198        /* rv */ std::ffi::c_int,
199        /* fd */ std::ffi::c_uint,
200        /* offset */ linux_api::posix_types::kernel_off_t,
201        /* whence */ linux_api::unistd::LSeekWhence,
202    );
203    pub fn lseek(
204        ctx: &mut SyscallContext,
205        fd: std::ffi::c_uint,
206        offset: linux_api::posix_types::kernel_off_t,
207        whence: std::ffi::c_uint,
208    ) -> Result<linux_api::posix_types::kernel_off_t, SyscallError> {
209        let whence = linux_api::unistd::LSeekWhence::try_from(whence).map_err(|_| Errno::EINVAL)?;
210        let desc_table = ctx.objs.thread.descriptor_table_borrow(ctx.objs.host);
211        let file = Self::get_descriptor(&desc_table, fd)?.file();
212        file.lseek(offset, whence)
213    }
214
215    log_syscall!(
216        readahead,
217        /* rv */ std::ffi::c_int,
218        /* fd */ std::ffi::c_int,
219        /* offset */ linux_api::types::loff_t,
220        /* count */ linux_api::types::size_t
221    );
222    pub fn readahead(ctx: &mut SyscallContext) -> SyscallResult {
223        Self::legacy_syscall(cshadow::syscallhandler_readahead, ctx)
224    }
225
226    log_syscall!(
227        readlink,
228        /* rv */ std::ffi::c_int,
229        /* pathname */ SyscallStringArg,
230        /* TODO: format this when we have better support for output-buffers.
231         * https://github.com/shadow/shadow/issues/3694 */
232        /* buf */
233        *const std::ffi::c_void,
234        /* bufsize */ std::ffi::c_int,
235    );
236    pub fn readlink(_ctx: &mut SyscallContext) -> SyscallResult {
237        Err(SyscallError::Native)
238    }
239
240    log_syscall!(
241        sync_file_range,
242        /* rv */ std::ffi::c_int,
243        /* fd */ std::ffi::c_int,
244        /* offset */ linux_api::types::loff_t,
245        /* nbytes */ linux_api::types::loff_t,
246        /* flags */ std::ffi::c_uint
247    );
248    pub fn sync_file_range(ctx: &mut SyscallContext) -> SyscallResult {
249        Self::legacy_syscall(cshadow::syscallhandler_sync_file_range, ctx)
250    }
251
252    log_syscall!(
253        syncfs,
254        /* rv */ std::ffi::c_int,
255        /* fd */ std::ffi::c_int
256    );
257    pub fn syncfs(ctx: &mut SyscallContext) -> SyscallResult {
258        Self::legacy_syscall(cshadow::syscallhandler_syncfs, ctx)
259    }
260}