Skip to content

Commit 10d5a34

Browse files
committed
Port to FreeBSD
Closes #223
2 parents ad8182f + 97341da commit 10d5a34

File tree

11 files changed

+126
-61
lines changed

11 files changed

+126
-61
lines changed

.cirrus.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
freebsd_instance:
2+
image: freebsd-15-0-release-amd64-zfs
3+
4+
env:
5+
RUST_BACKTRACE: full
6+
7+
task:
8+
name: FreeBSD
9+
setup_script:
10+
- fetch https://sh.rustup.rs -o rustup.sh
11+
- sh rustup.sh -y --profile minimal
12+
cargo_cache:
13+
folder: $HOME/.cargo/registry
14+
test_script:
15+
- . $HOME/.cargo/env
16+
- cargo test
17+
- cargo test --release
18+
before_cache_script:
19+
- rm -rf $HOME/.cargo/registry/index

src/fs.rs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,13 @@ impl AsyncFd {
327327

328328
/// Manipulate file space.
329329
///
330-
/// Manipulate the allocated disk space for the file referred for the byte
330+
/// Ensures that disk space is allocated for the file for the bytes in the
331331
/// range starting at `offset` and continuing for `length` bytes.
332+
///
333+
/// If the size of the file is less than `offset` + `size`, then the file is
334+
/// increased to this size; otherwise the file size is left unchanged.
332335
#[doc = man_link!(fallocate(2))]
336+
#[doc = man_link!(posix_fallocate(3))]
333337
#[doc(alias = "fallocate")]
334338
#[doc(alias = "posix_fallocate")]
335339
#[cfg(any(
@@ -339,17 +343,8 @@ impl AsyncFd {
339343
target_os = "linux",
340344
target_os = "netbsd",
341345
))]
342-
pub fn allocate<'fd>(
343-
&'fd self,
344-
offset: u64,
345-
length: u32,
346-
mode: Option<AllocateFlag>,
347-
) -> Allocate<'fd> {
348-
let mode = match mode {
349-
Some(mode) => mode,
350-
None => AllocateFlag(0),
351-
};
352-
Allocate::new(self, (), (offset, length, mode))
346+
pub fn allocate<'fd>(&'fd self, offset: u64, length: u32) -> Allocate<'fd> {
347+
Allocate::new(self, (), (offset, length, AllocateMode(0)))
353348
}
354349

355350
/// Truncate the file to `length`.
@@ -423,8 +418,10 @@ new_flag!(
423418
DONT_NEED = libc::POSIX_FADV_DONTNEED,
424419
}
425420

426-
/// Mode for call to [`AsyncFd::allocate`].
427-
pub struct AllocateFlag(u32) impl BitOr {
421+
/// Mode for [`AsyncFd::allocate`].
422+
///
423+
/// Set using [`Allocate::mode`].
424+
pub struct AllocateMode(u32) impl BitOr {
428425
/// Keep the same file size.
429426
#[cfg(any(target_os = "android", target_os = "linux"))]
430427
KEEP_SIZE = libc::FALLOC_FL_KEEP_SIZE,
@@ -473,11 +470,11 @@ fd_operation!(
473470
pub struct Allocate(sys::fs::AllocateOp) -> io::Result<()>;
474471
);
475472

473+
#[cfg(any(target_os = "android", target_os = "linux"))]
476474
impl<'fd> Stat<'fd> {
477475
/// Set which field(s) of the metadata the kernel should fill.
478476
///
479477
/// Defaults to filling some basic fields.
480-
#[cfg(any(target_os = "android", target_os = "linux"))]
481478
pub fn only(mut self, mask: MetadataInterest) -> Self {
482479
if let Some(args) = self.state.args_mut() {
483480
*args = mask;
@@ -486,6 +483,20 @@ impl<'fd> Stat<'fd> {
486483
}
487484
}
488485

486+
#[cfg(any(target_os = "android", target_os = "linux"))]
487+
impl<'fd> Allocate<'fd> {
488+
/// Manipulate the allocated disk space for the file other than allocating
489+
/// space for it.
490+
///
491+
/// Defaults to allocating the space.
492+
pub fn mode(mut self, mode: AllocateMode) -> Self {
493+
if let Some((_, _, m)) = self.state.args_mut() {
494+
*m = mode;
495+
}
496+
self
497+
}
498+
}
499+
489500
/// Metadata information about a file.
490501
///
491502
/// See [`AsyncFd::metadata`] and [`Stat`].

src/io_uring/fs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::ptr;
55
use std::time::{Duration, SystemTime};
66

77
use crate::fs::{
8-
AdviseFlag, AllocateFlag, FileType, Metadata, MetadataInterest, Permissions, RemoveFlag,
8+
AdviseFlag, AllocateMode, FileType, Metadata, MetadataInterest, Permissions, RemoveFlag,
99
SyncDataFlag, path_from_cstring,
1010
};
1111
use crate::io_uring::op::{FdOp, Op, OpExtract, OpReturn};
@@ -302,7 +302,7 @@ pub(crate) struct AllocateOp;
302302
impl FdOp for AllocateOp {
303303
type Output = ();
304304
type Resources = ();
305-
type Args = (u64, u32, AllocateFlag); // offset, length, mode
305+
type Args = (u64, u32, AllocateMode); // offset, length, mode
306306

307307
#[allow(clippy::cast_sign_loss)]
308308
fn fill_submission(

src/kqueue/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ pub(crate) struct AllocateOp;
239239
impl DirectFdOp for AllocateOp {
240240
type Output = ();
241241
type Resources = ();
242-
type Args = (u64, u32, crate::fs::AllocateFlag); // offset, length, mode
242+
type Args = (u64, u32, crate::fs::AllocateMode); // offset, length, mode
243243

244244
fn run(
245245
fd: &AsyncFd,

src/kqueue/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ pub(crate) struct Event(libc::kevent);
166166

167167
impl Event {
168168
/// Returns an error from the event, if any.
169+
#[allow(clippy::unnecessary_cast)]
169170
fn error(&self) -> Option<io::Error> {
170171
// We can't use references to packed structures (in checking the ignored
171172
// errors), so we need copy the data out before use.

src/kqueue/net.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl DirectOp for SocketOp {
3535
target_os = "netbsd",
3636
target_os = "openbsd",
3737
))]
38-
let r#type = r#type.0.cast_signed() | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
38+
let r#type = r#type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
3939

4040
let socket = syscall!(socket(domain.0, r#type, protocol.0.cast_signed()))?;
4141
// SAFETY: just created the socket above.

src/kqueue/process.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::mem::{MaybeUninit, replace};
1+
use std::mem::{self, MaybeUninit, replace};
22
use std::os::fd::RawFd;
33
use std::task::{self, Poll};
44
use std::{io, ptr};
@@ -16,6 +16,7 @@ impl crate::op::Op for WaitIdOp {
1616
type Args = (WaitOn, WaitOption);
1717
type State = EventedState<Self::Resources, Self::Args>;
1818

19+
#[allow(clippy::useless_conversion)]
1920
fn poll(
2021
state: &mut Self::State,
2122
ctx: &mut task::Context<'_>,
@@ -53,7 +54,7 @@ impl crate::op::Op for WaitIdOp {
5354
};
5455

5556
let options = options.0.cast_signed() | libc::WNOHANG; // Don't block.
56-
syscall!(waitid(id_type, pid, &raw mut info.0, options))?;
57+
syscall!(waitid(id_type, pid.into(), &raw mut info.0, options))?;
5758

5859
if info.0.si_pid == 0 {
5960
// Got polled without the process stopping, will have to
@@ -108,7 +109,7 @@ fn register_signals(kfd: RawFd, signals: &SignalSet) -> io::Result<()> {
108109
filter: libc::EVFILT_SIGNAL,
109110
flags: libc::EV_ADD,
110111
// SAFETY: all zeros is valid for `kevent`.
111-
..unsafe { std::mem::zeroed() }
112+
..unsafe { mem::zeroed() }
112113
});
113114
n_changes += 1;
114115
}
@@ -125,9 +126,20 @@ fn register_signals(kfd: RawFd, signals: &SignalSet) -> io::Result<()> {
125126
}
126127

127128
fn sigaction(signals: &SignalSet, action: libc::sighandler_t) -> io::Result<()> {
129+
#[cfg(any(
130+
target_os = "ios",
131+
target_os = "macos",
132+
target_os = "tvos",
133+
target_os = "visionos",
134+
target_os = "watchos",
135+
))]
136+
let sa_mask = 0;
137+
#[cfg(target_os = "freebsd")]
138+
let sa_mask = SignalSet::empty()?.0;
139+
128140
let action = libc::sigaction {
129141
sa_sigaction: action,
130-
sa_mask: 0,
142+
sa_mask,
131143
sa_flags: 0,
132144
};
133145
for signal in Signal::ALL_VALUES {

src/mem.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ new_flag!(
108108
#[cfg(any(target_os = "ios", target_os = "macos", target_os = "tvos", target_os = "visionos", target_os = "watchos"))]
109109
ZERO = libc::MADV_ZERO,
110110
*/
111+
/// Don't flush the data associated with this map to physical backing
112+
/// store unless it needs to.
113+
#[cfg(target_os = "freebsd")]
114+
NO_SYNC = libc::MADV_NOSYNC,
115+
/// Undoes the effects of [`AdviseFlag::NO_SYNC`] for any future pages
116+
/// dirtied within the address range.
117+
#[cfg(target_os = "freebsd")]
118+
AUTO_SYNC = libc::MADV_AUTOSYNC,
119+
/// Region is not included in a core file.
120+
#[cfg(target_os = "freebsd")]
121+
NO_CORE = libc::MADV_NOCORE,
122+
/// Include region in a core file.
123+
#[cfg(target_os = "freebsd")]
124+
CORE = libc::MADV_CORE,
125+
/// Informs the VM system this process should not be killed when the
126+
/// swap space is exhausted. The process must have superuser privileges.
127+
/// This should be used judiciously in processes that must remain
128+
/// running for the system to properly function.
129+
#[cfg(target_os = "freebsd")]
130+
PROTECT = libc::MADV_PROTECT,
111131
}
112132
);
113133

src/net.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ new_flag!(
5151
#[cfg(any(target_os = "android", target_os = "linux"))]
5252
PACKET = libc::AF_PACKET,
5353
/// Domain for low-level VSOCK interface.
54+
#[cfg(not(target_os = "freebsd"))]
5455
VSOCK = libc::AF_VSOCK,
5556
}
5657

@@ -91,12 +92,12 @@ new_flag!(
9192
/// User Datagram Protocol.
9293
UDP = libc::IPPROTO_UDP,
9394
/// Datagram Congestion Control Protocol.
94-
#[cfg(any(target_os = "android", target_os = "linux"))]
95+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
9596
DCCP = libc::IPPROTO_DCCP,
9697
/// Stream Control Transport Protocol.
9798
SCTP = libc::IPPROTO_SCTP,
9899
/// UDP-Lite.
99-
#[cfg(any(target_os = "android", target_os = "linux"))]
100+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
100101
UDPLITE = libc::IPPROTO_UDPLITE,
101102
/// Raw IP packets.
102103
RAW = libc::IPPROTO_RAW,
@@ -410,7 +411,7 @@ new_flag!(
410411
pub struct RecvFlag(u32) impl BitOr {
411412
/// Set the close-on-exec flag for the file descriptor received via a
412413
/// UNIX domain file descriptor using the `SCM_RIGHTS` operation.
413-
#[cfg(any(target_os = "android", target_os = "linux"))]
414+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
414415
CMSG_CLOEXEC = libc::MSG_CMSG_CLOEXEC,
415416
/// This flag specifies that queued errors should be received from the
416417
/// socket error queue.
@@ -538,7 +539,7 @@ new_flag!(
538539
#[cfg(any(target_os = "android", target_os = "linux"))]
539540
DETACH_BPF = libc::SO_DETACH_BPF,
540541
/// Domain.
541-
#[cfg(any(target_os = "android", target_os = "linux"))]
542+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
542543
DOMAIN = libc::SO_DOMAIN,
543544
/// Get and clear the pending socket error.
544545
ERROR = libc::SO_ERROR,
@@ -577,7 +578,7 @@ new_flag!(
577578
#[cfg(any(target_os = "android", target_os = "linux"))]
578579
PRIORITY = libc::SO_PRIORITY,
579580
/// Retrieves the socket protocol.
580-
#[cfg(any(target_os = "android", target_os = "linux"))]
581+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
581582
PROTOCOL = libc::SO_PROTOCOL,
582583
/// Maximum receive buffer in bytes.
583584
RECV_BUF = libc::SO_RCVBUF,
@@ -678,6 +679,7 @@ new_flag!(
678679
#[cfg(any(target_os = "android", target_os = "linux"))]
679680
PASS_SEC = libc::IP_PASSSEC,
680681
/// Collect information about this socket.
682+
#[cfg(not(target_os = "freebsd"))]
681683
PKT_INFO = libc::IP_PKTINFO,
682684
/// Enable extended reliable error message passing.
683685
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -687,7 +689,7 @@ new_flag!(
687689
#[cfg(any(target_os = "android", target_os = "linux"))]
688690
RECV_OPTS = libc::IP_RECVOPTS,
689691
/// Enables the `IP_ORIGDSTADDR` ancillary message in `recvmsg(2)`.
690-
#[cfg(any(target_os = "android", target_os = "linux"))]
692+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
691693
RECV_ORIG_DST_ADDR = libc::IP_RECVORIGDSTADDR,
692694
/// Enable passing of `IP_TOS` in ancillary message with incoming
693695
/// packets.
@@ -783,7 +785,7 @@ new_flag!(
783785
#[doc = man_link!(tcp(7))]
784786
pub struct TcpOpt(u32) {
785787
/// Set the TCP congestion control algorithm to be used.
786-
#[cfg(any(target_os = "android", target_os = "linux"))]
788+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
787789
CONGESTION = libc::TCP_CONGESTION,
788790
/// Don't send out partial frames.
789791
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -793,14 +795,14 @@ new_flag!(
793795
#[cfg(any(target_os = "android", target_os = "linux"))]
794796
DEFER_ACCEPT = libc::TCP_DEFER_ACCEPT,
795797
/// Collect information about this socket.
796-
#[cfg(any(target_os = "android", target_os = "linux"))]
798+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
797799
INFO = libc::TCP_INFO,
798800
/// The maximum number of keepalive probes TCP should send before
799801
/// dropping the connection.
800802
KEEP_CNT = libc::TCP_KEEPCNT,
801803
/// The time (in seconds) the connection needs to remain idle before TCP
802804
/// starts sending keepalive probes.
803-
#[cfg(any(target_os = "android", target_os = "linux"))]
805+
#[cfg(any(target_os = "android", target_os = "freebsd", target_os = "linux"))]
804806
KEEP_IDLE = libc::TCP_KEEPIDLE,
805807
/// The time (in seconds) between individual keepalive probes.
806808
KEEP_INTVL = libc::TCP_KEEPINTVL,
@@ -1597,7 +1599,7 @@ impl private::SocketAddress for unix::net::SocketAddr {
15971599
fn into_storage(self) -> Self::Storage {
15981600
let mut storage = libc::sockaddr_un {
15991601
// A number of OS have `sin6_len`, but we don't use it.
1600-
#[cfg(not(any(target_os = "android", target_os = "linux")))]
1602+
#[cfg(not(any(target_os = "android", target_os = "freebsd", target_os = "linux")))]
16011603
sun_len: 0,
16021604
sun_family: libc::AF_UNIX as libc::sa_family_t,
16031605
// SAFETY: all zero is valid for `sockaddr_un`.

0 commit comments

Comments
 (0)