diff --git a/example/linux/main.go b/example/linux/main.go index 7a416c7..bff1240 100644 --- a/example/linux/main.go +++ b/example/linux/main.go @@ -142,8 +142,12 @@ func main() { }) // socket device (optional) + vsockDevice, err := vz.NewVirtioSocketDeviceConfiguration() + if err != nil { + panic(err) + } config.SetSocketDevicesVirtualMachineConfiguration([]vz.SocketDeviceConfiguration{ - vz.NewVirtioSocketDeviceConfiguration(), + vsockDevice, }) validated, err := config.Validate() if !validated || err != nil { diff --git a/socket.go b/socket.go index 010cf14..9c9dbf9 100644 --- a/socket.go +++ b/socket.go @@ -44,7 +44,14 @@ type VirtioSocketDeviceConfiguration struct { } // NewVirtioSocketDeviceConfiguration creates a new VirtioSocketDeviceConfiguration. -func NewVirtioSocketDeviceConfiguration() *VirtioSocketDeviceConfiguration { +// +// This is only supported on macOS 11 and newer, ErrUnsupportedOSVersion will +// be returned on older versions. +func NewVirtioSocketDeviceConfiguration() (*VirtioSocketDeviceConfiguration, error) { + if macosMajorVersionLessThan(11) { + return nil, ErrUnsupportedOSVersion + } + config := &VirtioSocketDeviceConfiguration{ pointer: pointer{ ptr: C.newVZVirtioSocketDeviceConfiguration(), @@ -53,7 +60,7 @@ func NewVirtioSocketDeviceConfiguration() *VirtioSocketDeviceConfiguration { runtime.SetFinalizer(config, func(self *VirtioSocketDeviceConfiguration) { self.Release() }) - return config + return config, nil } // VirtioSocketDevice a device that manages port-based connections between the guest system and the host computer. @@ -137,7 +144,14 @@ var shouldAcceptNewConnectionHandlers = map[unsafe.Pointer]func(conn *VirtioSock // // The handler is executed asynchronously. Be sure to close the connection used in the handler by calling `conn.Close`. // This is to prevent connection leaks. -func NewVirtioSocketListener(handler func(conn *VirtioSocketConnection, err error)) *VirtioSocketListener { +// +// This is only supported on macOS 11 and newer, ErrUnsupportedOSVersion will +// be returned on older versions. +func NewVirtioSocketListener(handler func(conn *VirtioSocketConnection, err error)) (*VirtioSocketListener, error) { + if macosMajorVersionLessThan(11) { + return nil, ErrUnsupportedOSVersion + } + ptr := C.newVZVirtioSocketListener() listener := &VirtioSocketListener{ pointer: pointer{ @@ -163,7 +177,7 @@ func NewVirtioSocketListener(handler func(conn *VirtioSocketConnection, err erro runtime.SetFinalizer(listener, func(self *VirtioSocketListener) { self.Release() }) - return listener + return listener, nil } //export shouldAcceptNewConnectionHandler diff --git a/virtualization.h b/virtualization.h index d44ce35..a115806 100644 --- a/virtualization.h +++ b/virtualization.h @@ -21,7 +21,7 @@ bool shouldAcceptNewConnectionHandler(void *listener, void *connection, void *so /* VZVirtioSocketListener */ @interface VZVirtioSocketListenerDelegateImpl : NSObject -- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice; +- (BOOL)listener:(void *)listener shouldAcceptNewConnection:(void *)connection fromSocketDevice:(void *)socketDevice; @end /* BootLoader */ diff --git a/virtualization.m b/virtualization.m index 2defdd5..682ef16 100644 --- a/virtualization.m +++ b/virtualization.m @@ -36,9 +36,13 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N @end @implementation VZVirtioSocketListenerDelegateImpl -- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice; +- (BOOL)listener:(void *)listener shouldAcceptNewConnection:(void *)connection fromSocketDevice:(void *)socketDevice; { - return (BOOL)shouldAcceptNewConnectionHandler(listener, connection, socketDevice); + if (@available(macOS 11, *)) { + return (BOOL)shouldAcceptNewConnectionHandler((VZVirtioSocketListener *)listener, (VZVirtioSocketConnection *)connection, (VZVirtioSocketDevice *)socketDevice); + } else { + return false; + } } @end @@ -256,7 +260,9 @@ void setSerialPortsVZVirtualMachineConfiguration(void *config, void setSocketDevicesVZVirtualMachineConfiguration(void *config, void *socketDevices) { - [(VZVirtualMachineConfiguration *)config setSocketDevices:[(NSMutableArray *)socketDevices copy]]; + if (@available(macOS 11, *)) { + [(VZVirtualMachineConfiguration *)config setSocketDevices:[(NSMutableArray *)socketDevices copy]]; + } } /*! @@ -670,7 +676,11 @@ void setStreamsVZVirtioSoundDeviceConfiguration(void *audioDeviceConfiguration, */ void *newVZVirtioSocketDeviceConfiguration() { - return [[VZVirtioSocketDeviceConfiguration alloc] init]; + if (@available(macOS 11, *)) { + return [[VZVirtioSocketDeviceConfiguration alloc] init]; + } else { + return nil; + } } /*! @@ -684,9 +694,13 @@ void setStreamsVZVirtioSoundDeviceConfiguration(void *audioDeviceConfiguration, */ void *newVZVirtioSocketListener() { - VZVirtioSocketListener *ret = [[VZVirtioSocketListener alloc] init]; - [ret setDelegate:[[VZVirtioSocketListenerDelegateImpl alloc] init]]; - return ret; + if (@available(macOS 11, *)) { + VZVirtioSocketListener *ret = [[VZVirtioSocketListener alloc] init]; + [ret setDelegate:[[VZVirtioSocketListenerDelegateImpl alloc] init]]; + return ret; + } else { + return nil; + } } /*! @@ -700,9 +714,11 @@ void setStreamsVZVirtioSoundDeviceConfiguration(void *audioDeviceConfiguration, */ void VZVirtioSocketDevice_setSocketListenerForPort(void *socketDevice, void *vmQueue, void *listener, uint32_t port) { - dispatch_sync((dispatch_queue_t)vmQueue, ^{ - [(VZVirtioSocketDevice *)socketDevice setSocketListener:(VZVirtioSocketListener *)listener forPort:port]; - }); + if (@available(macOS 11, *)) { + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice setSocketListener:(VZVirtioSocketListener *)listener forPort:port]; + }); + } } /*! @@ -712,9 +728,11 @@ void VZVirtioSocketDevice_setSocketListenerForPort(void *socketDevice, void *vmQ */ void VZVirtioSocketDevice_removeSocketListenerForPort(void *socketDevice, void *vmQueue, uint32_t port) { - dispatch_sync((dispatch_queue_t)vmQueue, ^{ - [(VZVirtioSocketDevice *)socketDevice removeSocketListenerForPort:port]; - }); + if (@available(macOS 11, *)) { + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice removeSocketListenerForPort:port]; + }); + } } /*! @@ -726,20 +744,24 @@ void VZVirtioSocketDevice_removeSocketListenerForPort(void *socketDevice, void * */ void VZVirtioSocketDevice_connectToPort(void *socketDevice, void *vmQueue, uint32_t port, void *cgoHandlerPtr) { - dispatch_sync((dispatch_queue_t)vmQueue, ^{ - [(VZVirtioSocketDevice *)socketDevice connectToPort:port - completionHandler:^(VZVirtioSocketConnection *connection, NSError *err) { - connectionHandler(connection, err, cgoHandlerPtr); - }]; - }); + if (@available(macOS 11, *)) { + dispatch_sync((dispatch_queue_t)vmQueue, ^{ + [(VZVirtioSocketDevice *)socketDevice connectToPort:port + completionHandler:^(VZVirtioSocketConnection *connection, NSError *err) { + connectionHandler(connection, err, cgoHandlerPtr); + }]; + }); + } } VZVirtioSocketConnectionFlat convertVZVirtioSocketConnection2Flat(void *connection) { VZVirtioSocketConnectionFlat ret; - ret.sourcePort = [(VZVirtioSocketConnection *)connection sourcePort]; - ret.destinationPort = [(VZVirtioSocketConnection *)connection destinationPort]; - ret.fileDescriptor = [(VZVirtioSocketConnection *)connection fileDescriptor]; + if (@available(macOS 11, *)) { + ret.sourcePort = [(VZVirtioSocketConnection *)connection sourcePort]; + ret.destinationPort = [(VZVirtioSocketConnection *)connection destinationPort]; + ret.fileDescriptor = [(VZVirtioSocketConnection *)connection fileDescriptor]; + } return ret; } @@ -778,7 +800,11 @@ VZVirtioSocketConnectionFlat convertVZVirtioSocketConnection2Flat(void *connecti */ void *VZVirtualMachine_socketDevices(void *machine) { - return [(VZVirtualMachine *)machine socketDevices]; // NSArray + if (@available(macOS 11, *)) { + return [(VZVirtualMachine *)machine socketDevices]; // NSArray + } else { + return nil; + } } /*!