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::descriptor::CompatFile;
7use crate::host::syscall::File;
8use crate::host::syscall::handler::{SyscallContext, SyscallHandler};
9use crate::host::syscall::type_formatting::SyscallStringArg;
10use crate::host::syscall::types::{SyscallError, SyscallResult};
11
12impl SyscallHandler {
13    log_syscall!(
14        open,
15        /* rv */ std::ffi::c_int,
16        /* pathname */ SyscallStringArg,
17        /* flags */ linux_api::fcntl::OFlag,
18        /* mode */ nix::sys::stat::Mode,
19    );
20    pub fn open(
21        ctx: &mut SyscallContext,
22        _path: ForeignPtr<()>,
23        _flags: std::ffi::c_int,
24        _mode: kernel_mode_t,
25    ) -> SyscallResult {
26        Self::legacy_syscall(cshadow::syscallhandler_open, ctx)
27    }
28
29    log_syscall!(creat, /* rv */ std::ffi::c_int);
30    pub fn creat(ctx: &mut SyscallContext) -> SyscallResult {
31        Self::legacy_syscall(cshadow::syscallhandler_creat, ctx)
32    }
33
34    log_syscall!(fadvise64, /* rv */ std::ffi::c_int);
35    pub fn fadvise64(ctx: &mut SyscallContext) -> SyscallResult {
36        Self::legacy_syscall(cshadow::syscallhandler_fadvise64, ctx)
37    }
38
39    log_syscall!(fallocate, /* rv */ std::ffi::c_int);
40    pub fn fallocate(ctx: &mut SyscallContext) -> SyscallResult {
41        Self::legacy_syscall(cshadow::syscallhandler_fallocate, ctx)
42    }
43
44    log_syscall!(fchmod, /* rv */ std::ffi::c_int);
45    pub fn fchmod(ctx: &mut SyscallContext) -> SyscallResult {
46        Self::legacy_syscall(cshadow::syscallhandler_fchmod, ctx)
47    }
48
49    log_syscall!(fchown, /* rv */ std::ffi::c_int);
50    pub fn fchown(ctx: &mut SyscallContext) -> SyscallResult {
51        Self::legacy_syscall(cshadow::syscallhandler_fchown, ctx)
52    }
53
54    log_syscall!(fdatasync, /* rv */ std::ffi::c_int);
55    pub fn fdatasync(ctx: &mut SyscallContext) -> SyscallResult {
56        Self::legacy_syscall(cshadow::syscallhandler_fdatasync, ctx)
57    }
58
59    log_syscall!(fgetxattr, /* rv */ std::ffi::c_int);
60    pub fn fgetxattr(ctx: &mut SyscallContext) -> SyscallResult {
61        Self::legacy_syscall(cshadow::syscallhandler_fgetxattr, ctx)
62    }
63
64    log_syscall!(flistxattr, /* rv */ std::ffi::c_int);
65    pub fn flistxattr(ctx: &mut SyscallContext) -> SyscallResult {
66        Self::legacy_syscall(cshadow::syscallhandler_flistxattr, ctx)
67    }
68
69    log_syscall!(flock, /* rv */ std::ffi::c_int);
70    pub fn flock(ctx: &mut SyscallContext) -> SyscallResult {
71        Self::legacy_syscall(cshadow::syscallhandler_flock, ctx)
72    }
73
74    log_syscall!(fremovexattr, /* rv */ std::ffi::c_int);
75    pub fn fremovexattr(ctx: &mut SyscallContext) -> SyscallResult {
76        Self::legacy_syscall(cshadow::syscallhandler_fremovexattr, ctx)
77    }
78
79    log_syscall!(fsetxattr, /* rv */ std::ffi::c_int);
80    pub fn fsetxattr(ctx: &mut SyscallContext) -> SyscallResult {
81        Self::legacy_syscall(cshadow::syscallhandler_fsetxattr, ctx)
82    }
83
84    log_syscall!(fsync, /* rv */ std::ffi::c_int);
85    pub fn fsync(ctx: &mut SyscallContext) -> SyscallResult {
86        Self::legacy_syscall(cshadow::syscallhandler_fsync, ctx)
87    }
88
89    log_syscall!(ftruncate, /* rv */ std::ffi::c_int);
90    pub fn ftruncate(ctx: &mut SyscallContext) -> SyscallResult {
91        Self::legacy_syscall(cshadow::syscallhandler_ftruncate, ctx)
92    }
93
94    log_syscall!(getdents, /* rv */ std::ffi::c_int);
95    pub fn getdents(ctx: &mut SyscallContext) -> SyscallResult {
96        Self::legacy_syscall(cshadow::syscallhandler_getdents, ctx)
97    }
98
99    log_syscall!(getdents64, /* rv */ std::ffi::c_int);
100    pub fn getdents64(ctx: &mut SyscallContext) -> SyscallResult {
101        Self::legacy_syscall(cshadow::syscallhandler_getdents64, ctx)
102    }
103
104    log_syscall!(
105        lseek,
106        /* rv */ std::ffi::c_int,
107        /* fd */ std::ffi::c_uint,
108        /* offset */ linux_api::posix_types::kernel_off_t,
109        /* whence */ std::ffi::c_uint,
110    );
111    pub fn lseek(
112        ctx: &mut SyscallContext,
113        fd: std::ffi::c_uint,
114        _offset: linux_api::posix_types::kernel_off_t,
115        _whence: std::ffi::c_uint,
116    ) -> Result<linux_api::posix_types::kernel_off_t, SyscallError> {
117        let desc_table = ctx.objs.thread.descriptor_table_borrow(ctx.objs.host);
118
119        let file = {
120            match Self::get_descriptor(&desc_table, fd)?.file() {
121                CompatFile::New(file) => file,
122                // if it's a legacy file, use the C syscall handler instead
123                CompatFile::Legacy(_) => {
124                    drop(desc_table);
125                    return Self::legacy_syscall(cshadow::syscallhandler_lseek, ctx);
126                }
127            }
128        };
129
130        match file.inner_file() {
131            File::Pipe(_) => Err(Errno::ESPIPE.into()),
132            _ => {
133                warn_once_then_debug!("lseek() is not implemented for this type");
134                Err(Errno::ENOTSUP.into())
135            }
136        }
137    }
138
139    log_syscall!(readahead, /* rv */ std::ffi::c_int);
140    pub fn readahead(ctx: &mut SyscallContext) -> SyscallResult {
141        Self::legacy_syscall(cshadow::syscallhandler_readahead, ctx)
142    }
143
144    log_syscall!(sync_file_range, /* rv */ std::ffi::c_int);
145    pub fn sync_file_range(ctx: &mut SyscallContext) -> SyscallResult {
146        Self::legacy_syscall(cshadow::syscallhandler_sync_file_range, ctx)
147    }
148
149    log_syscall!(syncfs, /* rv */ std::ffi::c_int);
150    pub fn syncfs(ctx: &mut SyscallContext) -> SyscallResult {
151        Self::legacy_syscall(cshadow::syscallhandler_syncfs, ctx)
152    }
153}