From b1aa1172d694ed0c6d4a8b80b64d3750174c4acb Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Mon, 6 Apr 2026 16:51:39 -0700 Subject: [PATCH 1/2] Actions: Add Linux build step To make sure the project (and many linux specific libraries) builds on linux lets add a linux step to build for both musl and glibc. Eventually this will run unit tests as well. --- .github/workflows/linux-build.yml | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/linux-build.yml diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml new file mode 100644 index 00000000..808f2dd2 --- /dev/null +++ b/.github/workflows/linux-build.yml @@ -0,0 +1,44 @@ +name: Linux build + +permissions: + contents: read + +on: + pull_request: + types: [opened, reopened, synchronize] + push: + branches: + - main + - release/* + +jobs: + build: + name: Linux compile check + if: github.repository == 'apple/containerization' + timeout-minutes: 30 + runs-on: ubuntu-24.04 + container: swift:6.3-noble + + steps: + - name: Checkout repository + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + with: + fetch-depth: 0 + + - name: Install system dependencies + run: apt-get update && apt-get install -y curl make libarchive-dev libbz2-dev liblzma-dev libssl-dev + + - name: Build containerization + run: make containerization + + - name: Build vminitd (glibc) + run: make -C vminitd SWIFT_CONFIGURATION="--disable-automatic-resolution -Xswiftc -warnings-as-errors" + + - name: Install Static Linux SDK + run: | + curl -L -o /tmp/static-linux-sdk.tar.gz https://download.swift.org/swift-6.3-release/static-sdk/swift-6.3-RELEASE/swift-6.3-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz + swift sdk install /tmp/static-linux-sdk.tar.gz + rm /tmp/static-linux-sdk.tar.gz + + - name: Build vminitd (musl) + run: make -C vminitd From 227201e9344b610f2aca502b71a450f3b1f06e88 Mon Sep 17 00:00:00 2001 From: Danny Canter Date: Mon, 6 Apr 2026 21:33:31 -0700 Subject: [PATCH 2/2] Make project libc agnostic Today there's quite a few things that do not compile if you change musl out for glibc. This is either due to type differences between what some of the syscall wrappers expect (enums vs. raw integers) or the fact that swifts glibc modulemap doesn't define gnu_source so some headers don't get included (vfs.h for statfs and pals). To work around this, we need to expose either compatability shims, or just expose the headers we need in our existing c shims we already have. --- .github/workflows/linux-build.yml | 6 +- Sources/CShim/include/linux_shim.h | 31 +++++++++ Sources/ContainerizationOS/Linux/Epoll.swift | 37 ++++++++--- vminitd/Makefile | 7 +- vminitd/Package.swift | 1 + vminitd/Sources/Cgroup/Cgroup2Manager.swift | 1 + vminitd/Sources/LCShim/include/syscall.h | 68 +++++++++++++++++++- vminitd/Sources/LCShim/syscall.c | 9 +++ vminitd/Sources/vmexec/Console.swift | 1 + vminitd/Sources/vmexec/RunCommand.swift | 2 +- vminitd/Sources/vmexec/vmexec.swift | 35 +++++----- vminitd/Sources/vminitd/AgentCommand.swift | 5 +- vminitd/Sources/vminitd/IOPair.swift | 2 +- vminitd/Sources/vminitd/OSFile+Splice.swift | 5 +- vminitd/Sources/vminitd/VsockProxy.swift | 11 ++-- 15 files changed, 171 insertions(+), 50 deletions(-) create mode 100644 Sources/CShim/include/linux_shim.h diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 808f2dd2..e7c7318c 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -14,7 +14,6 @@ on: jobs: build: name: Linux compile check - if: github.repository == 'apple/containerization' timeout-minutes: 30 runs-on: ubuntu-24.04 container: swift:6.3-noble @@ -35,10 +34,7 @@ jobs: run: make -C vminitd SWIFT_CONFIGURATION="--disable-automatic-resolution -Xswiftc -warnings-as-errors" - name: Install Static Linux SDK - run: | - curl -L -o /tmp/static-linux-sdk.tar.gz https://download.swift.org/swift-6.3-release/static-sdk/swift-6.3-RELEASE/swift-6.3-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz - swift sdk install /tmp/static-linux-sdk.tar.gz - rm /tmp/static-linux-sdk.tar.gz + run: make -C vminitd linux-sdk - name: Build vminitd (musl) run: make -C vminitd diff --git a/Sources/CShim/include/linux_shim.h b/Sources/CShim/include/linux_shim.h new file mode 100644 index 00000000..4e730037 --- /dev/null +++ b/Sources/CShim/include/linux_shim.h @@ -0,0 +1,31 @@ +/* + * Copyright © 2026 Apple Inc. and the Containerization project authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// The below fall into two main categories: +// 1. Aren't exposed by Swifts glibc modulemap. +// 2. Don't have syscall wrappers/definitions in glibc/musl. + +#ifndef __LINUX_SHIM_H +#define __LINUX_SHIM_H + +#if defined(__linux__) + +#include +#include + +#endif /* __linux__ */ + +#endif /* __LINUX_SHIM_H */ diff --git a/Sources/ContainerizationOS/Linux/Epoll.swift b/Sources/ContainerizationOS/Linux/Epoll.swift index e3249e38..f239be1f 100644 --- a/Sources/ContainerizationOS/Linux/Epoll.swift +++ b/Sources/ContainerizationOS/Linux/Epoll.swift @@ -14,24 +14,43 @@ // limitations under the License. //===----------------------------------------------------------------------===// +#if os(Linux) + #if canImport(Musl) import Musl +#elseif canImport(Glibc) +import Glibc +#endif +import CShim import Foundation import Synchronization +// On glibc, epoll constants are EPOLL_EVENTS enum values. On musl they're +// plain UInt32. These helpers normalize them to UInt32/Int32. +private func epollMask(_ value: UInt32) -> UInt32 { value } +private func epollMask(_ value: Int32) -> UInt32 { UInt32(bitPattern: value) } +#if canImport(Glibc) +private func epollMask(_ value: EPOLL_EVENTS) -> UInt32 { value.rawValue } +private func epollFlag(_ value: EPOLL_EVENTS) -> Int32 { Int32(bitPattern: value.rawValue) } +#endif + /// Register file descriptors to receive events via Linux's /// epoll syscall surface. public final class Epoll: Sendable { public typealias Mask = Int32 public typealias Handler = (@Sendable (Mask) -> Void) + public static let maskIn: Int32 = Int32(bitPattern: epollMask(EPOLLIN)) + public static let maskOut: Int32 = Int32(bitPattern: epollMask(EPOLLOUT)) + public static let defaultMask: Int32 = maskIn | maskOut + private let epollFD: Int32 private let handlers = SafeMap() private let pipe = Pipe() // to wake up a waiting epoll_wait public init() throws { - let efd = epoll_create1(EPOLL_CLOEXEC) + let efd = epoll_create1(Int32(EPOLL_CLOEXEC)) guard efd > 0 else { throw POSIXError.fromErrno() } @@ -41,14 +60,14 @@ public final class Epoll: Sendable { public func add( _ fd: Int32, - mask: Int32 = EPOLLIN | EPOLLOUT, // HUP is always added + mask: Int32 = Epoll.defaultMask, handler: @escaping Handler ) throws { guard fcntl(fd, F_SETFL, O_NONBLOCK) == 0 else { throw POSIXError.fromErrno() } - let events = EPOLLET | UInt32(bitPattern: mask) + let events = epollMask(EPOLLET) | UInt32(bitPattern: mask) var event = epoll_event() event.events = events @@ -115,7 +134,7 @@ public final class Epoll: Sendable { public func delete(_ fd: Int32) throws { var event = epoll_event() let result = withUnsafeMutablePointer(to: &event) { ptr in - epoll_ctl(self.epollFD, EPOLL_CTL_DEL, fd, ptr) + epoll_ctl(self.epollFD, EPOLL_CTL_DEL, fd, ptr) as Int32 } if result != 0 { if !acceptableDeletionErrno() { @@ -162,20 +181,20 @@ public final class Epoll: Sendable { extension Epoll.Mask { public var isHangup: Bool { - (self & (EPOLLHUP | EPOLLERR)) != 0 + (self & Int32(bitPattern: epollMask(EPOLLHUP) | epollMask(EPOLLERR))) != 0 } public var isRhangup: Bool { - (self & EPOLLRDHUP) != 0 + (self & Int32(bitPattern: epollMask(EPOLLRDHUP))) != 0 } public var readyToRead: Bool { - (self & EPOLLIN) != 0 + (self & Int32(bitPattern: epollMask(EPOLLIN))) != 0 } public var readyToWrite: Bool { - (self & EPOLLOUT) != 0 + (self & Int32(bitPattern: epollMask(EPOLLOUT))) != 0 } } -#endif // canImport(Musl) +#endif // os(Linux) diff --git a/vminitd/Makefile b/vminitd/Makefile index c9401cc2..505bff15 100644 --- a/vminitd/Makefile +++ b/vminitd/Makefile @@ -31,6 +31,7 @@ SWIFT_CONFIGURATION := --swift-sdk $(MUSL_ARCH)-swift-linux-musl $(SWIFT_WARNING SWIFT_VERSION := 6.3 SWIFT_SDK_URL := https://download.swift.org/swift-6.3-release/static-sdk/swift-6.3-RELEASE/swift-6.3-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz +SWIFT_SDK_CHECKSUM := d2078b69bdeb5c31202c10e9d8a11d6f66f82938b51a4b75f032ccb35c4c286c SWIFT_SDK_PATH := /tmp/$(notdir $(SWIFT_SDK_URL)) SYSTEM_TYPE := $(shell uname -s) @@ -64,7 +65,7 @@ all: @install "$(BUILD_BIN_DIR)/vmexec" ./bin/ .PHONY: cross-prep -cross-prep: linux-sdk +cross-prep: swift linux-sdk .PHONY: swiftly swiftly: @@ -84,10 +85,10 @@ swift: swiftly @${SWIFTLY_BIN_DIR}/swiftly install $(SWIFT_VERSION) .PHONY: linux-sdk -linux-sdk: swift +linux-sdk: @echo Installing Static Linux SDK... @curl -L -o $(SWIFT_SDK_PATH) $(SWIFT_SDK_URL) - -@$(SWIFT) sdk install $(SWIFT_SDK_PATH) + -@$(SWIFT) sdk install $(SWIFT_SDK_PATH) --checksum $(SWIFT_SDK_CHECKSUM) @rm $(SWIFT_SDK_PATH) .PHONY: clean diff --git a/vminitd/Package.swift b/vminitd/Package.swift index e2465a66..110414b1 100644 --- a/vminitd/Package.swift +++ b/vminitd/Package.swift @@ -56,6 +56,7 @@ let package = Package( .product(name: "ContainerizationOCI", package: "containerization"), .product(name: "ContainerizationOS", package: "containerization"), .product(name: "SystemPackage", package: "swift-system"), + "LCShim", ] ), .executableTarget( diff --git a/vminitd/Sources/Cgroup/Cgroup2Manager.swift b/vminitd/Sources/Cgroup/Cgroup2Manager.swift index 26c1b254..65ba6869 100644 --- a/vminitd/Sources/Cgroup/Cgroup2Manager.swift +++ b/vminitd/Sources/Cgroup/Cgroup2Manager.swift @@ -26,6 +26,7 @@ import Musl import Glibc #endif +import LCShim import ContainerizationOCI import ContainerizationOS import Foundation diff --git a/vminitd/Sources/LCShim/include/syscall.h b/vminitd/Sources/LCShim/include/syscall.h index f30e3ab2..dbbc8813 100644 --- a/vminitd/Sources/LCShim/include/syscall.h +++ b/vminitd/Sources/LCShim/include/syscall.h @@ -14,25 +14,87 @@ * limitations under the License. */ +// The below fall into two main categories: +// 1. Aren't exposed by Swifts glibc modulemap. +// 2. Don't have syscall wrappers/definitions in glibc/musl. + #ifndef __SYSCALL_H #define __SYSCALL_H #include +#include -int CZ_pivot_root(const char *new_root, const char *put_old); +// CLONE_* flags +#ifndef CLONE_NEWNS +#define CLONE_NEWNS 0x00020000 +#endif +#ifndef CLONE_NEWCGROUP +#define CLONE_NEWCGROUP 0x02000000 +#endif +#ifndef CLONE_NEWUTS +#define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +#define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +#define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +#define CLONE_NEWPID 0x20000000 +#endif + +extern int setns(int fd, int nstype); +extern int unshare(int flags); +extern int dup3(int oldfd, int newfd, int flags); +extern int execvpe(const char *file, char *const argv[], char *const envp[]); +extern int unlockpt(int fd); +extern char *ptsname(int fd); +// splice(2) and flags. +extern ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, + size_t len, unsigned int flags); +#ifndef SPLICE_F_MOVE +#define SPLICE_F_MOVE 1 +#endif +#ifndef SPLICE_F_NONBLOCK +#define SPLICE_F_NONBLOCK 2 +#endif + +// RLIMIT constants as plain integers. On glibc these are __rlimit_resource +// enum values which can't be used as Int32 in Swift. +#define CZ_RLIMIT_CPU 0 +#define CZ_RLIMIT_FSIZE 1 +#define CZ_RLIMIT_DATA 2 +#define CZ_RLIMIT_STACK 3 +#define CZ_RLIMIT_CORE 4 +#define CZ_RLIMIT_RSS 5 +#define CZ_RLIMIT_NPROC 6 +#define CZ_RLIMIT_NOFILE 7 +#define CZ_RLIMIT_MEMLOCK 8 +#define CZ_RLIMIT_AS 9 +#define CZ_RLIMIT_LOCKS 10 +#define CZ_RLIMIT_SIGPENDING 11 +#define CZ_RLIMIT_MSGQUEUE 12 +#define CZ_RLIMIT_NICE 13 +#define CZ_RLIMIT_RTPRIO 14 +#define CZ_RLIMIT_RTTIME 15 + +// setrlimit wrapper that accepts plain int for the resource parameter, +// avoiding glibc's __rlimit_resource enum type mismatch in Swift. +int CZ_setrlimit(int resource, unsigned long long soft, unsigned long long hard); + +int CZ_pivot_root(const char *new_root, const char *put_old); int CZ_set_sub_reaper(); #ifndef SYS_pidfd_open #define SYS_pidfd_open 434 #endif - int CZ_pidfd_open(pid_t pid, unsigned int flags); #ifndef SYS_pidfd_getfd #define SYS_pidfd_getfd 438 #endif - int CZ_pidfd_getfd(int pidfd, int targetfd, unsigned int flags); int CZ_prctl_set_no_new_privs(); diff --git a/vminitd/Sources/LCShim/syscall.c b/vminitd/Sources/LCShim/syscall.c index 4070196c..f65c75aa 100644 --- a/vminitd/Sources/LCShim/syscall.c +++ b/vminitd/Sources/LCShim/syscall.c @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -39,3 +40,11 @@ int CZ_pidfd_getfd(int pidfd, int targetfd, unsigned int flags) { int CZ_prctl_set_no_new_privs() { return prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); } + +int CZ_setrlimit(int resource, unsigned long long soft, + unsigned long long hard) { + struct rlimit limit; + limit.rlim_cur = (rlim_t)soft; + limit.rlim_max = (rlim_t)hard; + return setrlimit(resource, &limit); +} diff --git a/vminitd/Sources/vmexec/Console.swift b/vminitd/Sources/vmexec/Console.swift index 9fb25617..b868049f 100644 --- a/vminitd/Sources/vmexec/Console.swift +++ b/vminitd/Sources/vmexec/Console.swift @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// import FoundationEssentials +import LCShim #if canImport(Musl) import Musl diff --git a/vminitd/Sources/vmexec/RunCommand.swift b/vminitd/Sources/vmexec/RunCommand.swift index cb79716a..4c9607fb 100644 --- a/vminitd/Sources/vmexec/RunCommand.swift +++ b/vminitd/Sources/vmexec/RunCommand.swift @@ -81,7 +81,7 @@ struct RunCommand: ParsableCommand { guard statfs("/", &s) == 0 else { throw App.Errno(stage: "statfs(/)") } - flags |= s.f_flags + flags |= UInt(s.f_flags) guard mount("", "/", "", flags, "") == 0 else { throw App.Errno(stage: "mount rootfs ro") diff --git a/vminitd/Sources/vmexec/vmexec.swift b/vminitd/Sources/vmexec/vmexec.swift index cf8ba4db..8141be9d 100644 --- a/vminitd/Sources/vmexec/vmexec.swift +++ b/vminitd/Sources/vmexec/vmexec.swift @@ -158,46 +158,45 @@ extension App { static func setRLimits(rlimits: [ContainerizationOCI.POSIXRlimit]) throws { for rl in rlimits { - var limit = rlimit(rlim_cur: rl.soft, rlim_max: rl.hard) let resource: Int32 switch rl.type { case "RLIMIT_AS": - resource = RLIMIT_AS + resource = CZ_RLIMIT_AS case "RLIMIT_CORE": - resource = RLIMIT_CORE + resource = CZ_RLIMIT_CORE case "RLIMIT_CPU": - resource = RLIMIT_CPU + resource = CZ_RLIMIT_CPU case "RLIMIT_DATA": - resource = RLIMIT_DATA + resource = CZ_RLIMIT_DATA case "RLIMIT_FSIZE": - resource = RLIMIT_FSIZE + resource = CZ_RLIMIT_FSIZE case "RLIMIT_LOCKS": - resource = RLIMIT_LOCKS + resource = CZ_RLIMIT_LOCKS case "RLIMIT_MEMLOCK": - resource = RLIMIT_MEMLOCK + resource = CZ_RLIMIT_MEMLOCK case "RLIMIT_MSGQUEUE": - resource = RLIMIT_MSGQUEUE + resource = CZ_RLIMIT_MSGQUEUE case "RLIMIT_NICE": - resource = RLIMIT_NICE + resource = CZ_RLIMIT_NICE case "RLIMIT_NOFILE": - resource = RLIMIT_NOFILE + resource = CZ_RLIMIT_NOFILE case "RLIMIT_NPROC": - resource = RLIMIT_NPROC + resource = CZ_RLIMIT_NPROC case "RLIMIT_RSS": - resource = RLIMIT_RSS + resource = CZ_RLIMIT_RSS case "RLIMIT_RTPRIO": - resource = RLIMIT_RTPRIO + resource = CZ_RLIMIT_RTPRIO case "RLIMIT_RTTIME": - resource = RLIMIT_RTTIME + resource = CZ_RLIMIT_RTTIME case "RLIMIT_SIGPENDING": - resource = RLIMIT_SIGPENDING + resource = CZ_RLIMIT_SIGPENDING case "RLIMIT_STACK": - resource = RLIMIT_STACK + resource = CZ_RLIMIT_STACK default: errno = EINVAL throw App.Errno(stage: "rlimit key unknown") } - guard setrlimit(resource, &limit) == 0 else { + guard CZ_setrlimit(resource, rl.soft, rl.hard) == 0 else { throw App.Errno(stage: "setrlimit()") } } diff --git a/vminitd/Sources/vminitd/AgentCommand.swift b/vminitd/Sources/vminitd/AgentCommand.swift index 0918ed42..76eb7f78 100644 --- a/vminitd/Sources/vminitd/AgentCommand.swift +++ b/vminitd/Sources/vminitd/AgentCommand.swift @@ -192,12 +192,11 @@ struct AgentCommand: AsyncParsableCommand { private static func adjustLimits(_ log: Logger) throws { let nrOpen = try String(contentsOfFile: "/proc/sys/fs/nr_open", encoding: .utf8) .trimmingCharacters(in: .whitespacesAndNewlines) - guard let max = rlim_t(nrOpen) else { + guard let max = UInt64(nrOpen) else { throw POSIXError(.EINVAL) } log.debug("setting RLIMIT_NOFILE to \(max)") - var limits = rlimit(rlim_cur: max, rlim_max: max) - guard setrlimit(RLIMIT_NOFILE, &limits) == 0 else { + guard CZ_setrlimit(CZ_RLIMIT_NOFILE, max, max) == 0 else { throw POSIXError(.init(rawValue: errno)!) } } diff --git a/vminitd/Sources/vminitd/IOPair.swift b/vminitd/Sources/vminitd/IOPair.swift index f8b06623..4b8a78aa 100644 --- a/vminitd/Sources/vminitd/IOPair.swift +++ b/vminitd/Sources/vminitd/IOPair.swift @@ -118,7 +118,7 @@ final class IOPair: Sendable { let readFrom = OSFile(fd: readFromFd) let writeTo = OSFile(fd: writeToFd) - try ProcessSupervisor.default.poller.add(readFromFd, mask: EPOLLIN) { mask in + try ProcessSupervisor.default.poller.add(readFromFd, mask: Epoll.maskIn) { mask in self.io.withLock { io in if io.closed { return diff --git a/vminitd/Sources/vminitd/OSFile+Splice.swift b/vminitd/Sources/vminitd/OSFile+Splice.swift index 1c330b6e..5ba00569 100644 --- a/vminitd/Sources/vminitd/OSFile+Splice.swift +++ b/vminitd/Sources/vminitd/OSFile+Splice.swift @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// import Foundation +import LCShim extension OSFile { struct SpliceFile: Sendable { @@ -61,7 +62,7 @@ extension OSFile { while true { while (from.offset - to.offset) < count { let toRead = count - (from.offset - to.offset) - let bytesRead = Foundation.splice(from.fileDescriptor, nil, to.writer, nil, toRead, UInt32(bitPattern: SPLICE_F_MOVE | SPLICE_F_NONBLOCK)) + let bytesRead = LCShim.splice(from.fileDescriptor, nil, to.writer, nil, toRead, UInt32(bitPattern: LCShim.SPLICE_F_MOVE | LCShim.SPLICE_F_NONBLOCK)) if bytesRead == -1 { if errno != EAGAIN && errno != EIO { throw POSIXError(.init(rawValue: errno)!) @@ -81,7 +82,7 @@ extension OSFile { } while to.offset < from.offset { let toWrite = from.offset - to.offset - let bytesWrote = Foundation.splice(to.reader, nil, to.fileDescriptor, nil, toWrite, UInt32(bitPattern: SPLICE_F_MOVE | SPLICE_F_NONBLOCK)) + let bytesWrote = LCShim.splice(to.reader, nil, to.fileDescriptor, nil, toWrite, UInt32(bitPattern: LCShim.SPLICE_F_MOVE | LCShim.SPLICE_F_NONBLOCK)) if bytesWrote == -1 { if errno != EAGAIN && errno != EIO { throw POSIXError(.init(rawValue: errno)!) diff --git a/vminitd/Sources/vminitd/VsockProxy.swift b/vminitd/Sources/vminitd/VsockProxy.swift index 9e92d9fa..fabdc353 100644 --- a/vminitd/Sources/vminitd/VsockProxy.swift +++ b/vminitd/Sources/vminitd/VsockProxy.swift @@ -17,6 +17,7 @@ import ContainerizationIO import ContainerizationOS import Foundation +import LCShim import Logging actor VsockProxy { @@ -243,7 +244,7 @@ extension VsockProxy { c.resume() } - try! ProcessSupervisor.default.poller.add(clientFile.fileDescriptor, mask: EPOLLIN | EPOLLOUT) { mask in + try! ProcessSupervisor.default.poller.add(clientFile.fileDescriptor) { mask in if mask.readyToRead && !eofFromClient { let (fromEof, toEof) = Self.transferData( fromFile: &clientFile, @@ -274,7 +275,7 @@ extension VsockProxy { // we should see no more EPOLLIN events on the client fd // and no more EPOLLOUT events on the server fd eofFromClient = true - if shutdown(serverFile.fileDescriptor, SHUT_WR) != 0 { + if shutdown(serverFile.fileDescriptor, Int32(SHUT_WR)) != 0 { self.log?.warning( "failed to shut down client reads", metadata: [ @@ -295,7 +296,7 @@ extension VsockProxy { } } - try! ProcessSupervisor.default.poller.add(serverFile.fileDescriptor, mask: EPOLLIN | EPOLLOUT) { mask in + try! ProcessSupervisor.default.poller.add(serverFile.fileDescriptor) { mask in if mask.readyToRead && !eofFromServer { let (fromEof, toEof) = Self.transferData( fromFile: &serverFile, @@ -326,7 +327,7 @@ extension VsockProxy { // we should see no more EPOLLIN events on the server fd // and no more EPOLLOUT events on the client fd eofFromServer = true - if shutdown(clientFile.fileDescriptor, SHUT_WR) != 0 { + if shutdown(clientFile.fileDescriptor, Int32(SHUT_WR)) != 0 { self.log?.warning( "failed to shut down server reads", metadata: [ @@ -375,7 +376,7 @@ extension VsockProxy { // half close, shut down client to server transfer // we should see no more EPOLLIN events on the client fd // and no more EPOLLOUT events on the server fd - if shutdown(toFile.fileDescriptor, SHUT_WR) != 0 { + if shutdown(toFile.fileDescriptor, Int32(SHUT_WR)) != 0 { log?.warning( "failed to shut down reads", metadata: [