mirror of
https://github.com/apple/container.git
synced 2026-10-13 17:49:16 +00:00
Actions: Add Linux build step (#654)
Related to https://github.com/apple/containerization/issues/606 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. This change needs a bit more libc agnostic-ifying work to make sure things work for both libcs.
This commit is contained in:
1 parent
1a91899b63
commit
997d5a4b08
15 files changed
+210
-45
No files matched your search
@@ -0,0 +1,40 @@
|
||||
name: Linux build
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux compile check
|
||||
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: make -C vminitd linux-sdk
|
||||
|
||||
- name: Build vminitd (musl)
|
||||
run: make -C vminitd
|
||||
@@ -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 <sys/epoll.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
#endif /* __LINUX_SHIM_H */
|
||||
@@ -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<Int32, Handler>()
|
||||
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)
|
||||
+4
-3
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -26,6 +26,7 @@ import Musl
|
||||
import Glibc
|
||||
#endif
|
||||
|
||||
import LCShim
|
||||
import ContainerizationOCI
|
||||
import ContainerizationOS
|
||||
import Foundation
|
||||
|
||||
@@ -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 <sys/types.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
// 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();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import FoundationEssentials
|
||||
import LCShim
|
||||
|
||||
#if canImport(Musl)
|
||||
import Musl
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)!)
|
||||
|
||||
@@ -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: [
|
||||
|
||||
Reference in new issue
Block a user