diff options
Diffstat (limited to 'src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp')
-rw-r--r-- | src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp index 32ccf4c4..80e5b877 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2007 Oracle Corporation + * Copyright (C) 2007-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -36,14 +36,20 @@ # define INCL_ERRORS # include <os2.h> -#elif defined(RT_OS_FREEBSD) \ +#elif defined(RT_OS_DARWIN) \ + || defined(RT_OS_FREEBSD) \ + || defined(RT_OS_HAIKU) \ || defined(RT_OS_LINUX) \ || defined(RT_OS_SOLARIS) # include <sys/types.h> # include <sys/stat.h> -# if defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */ +# if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) /** @todo check this on solaris+freebsd as well. */ # include <sys/ioctl.h> # endif +# if defined(RT_OS_DARWIN) +# include <mach/mach_port.h> +# include <IOKit/IOKitLib.h> +# endif # include <errno.h> # include <unistd.h> #endif @@ -85,6 +91,10 @@ static RTFILE g_File = NIL_RTFILE; * inside a single process space. */ static uint32_t volatile g_cInits = 0; +#ifdef RT_OS_DARWIN +/** I/O Kit connection handle. */ +static io_connect_t g_uConnection = 0; +#endif @@ -189,6 +199,40 @@ static int vbglR3Init(const char *pszDeviceName) } g_File = (RTFILE)hf; +#elif defined(RT_OS_DARWIN) + /* + * Darwin is kind of special we need to engage the device via I/O first + * before we open it via the BSD device node. + */ + mach_port_t MasterPort; + kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &MasterPort); + if (kr != kIOReturnSuccess) + return VERR_GENERAL_FAILURE; + + CFDictionaryRef ClassToMatch = IOServiceMatching("org_virtualbox_VBoxGuest"); + if (!ClassToMatch) + return VERR_GENERAL_FAILURE; + + io_service_t ServiceObject = IOServiceGetMatchingService(kIOMasterPortDefault, ClassToMatch); + if (!ServiceObject) + return VERR_NOT_FOUND; + + io_connect_t uConnection; + kr = IOServiceOpen(ServiceObject, mach_task_self(), 0, &uConnection); + IOObjectRelease(ServiceObject); + if (kr != kIOReturnSuccess) + return VERR_OPEN_FAILED; + + RTFILE hFile; + int rc = RTFileOpen(&hFile, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); + if (RT_FAILURE(rc)) + { + IOServiceClose(uConnection); + return rc; + } + g_File = hFile; + g_uConnection = uConnection; + #elif defined(VBOX_VBGLR3_XFREE86) int File = xf86open(pszDeviceName, XF86_O_RDWR); if (File == -1) @@ -197,7 +241,7 @@ static int vbglR3Init(const char *pszDeviceName) #else - /* The default implementation. (linux, solaris, freebsd) */ + /* The default implementation. (linux, solaris, freebsd, haiku) */ RTFILE File; int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); if (RT_FAILURE(rc)) @@ -262,13 +306,22 @@ VBGLR3DECL(void) VbglR3Term(void) Assert(fRc); NOREF(fRc); # elif defined(RT_OS_OS2) - RTFILE File = g_File; g_File = NIL_RTFILE; AssertReturnVoid(File != NIL_RTFILE); APIRET rc = DosClose((uintptr_t)File); AssertMsg(!rc, ("%ld\n", rc)); +#elif defined(RT_OS_DARWIN) + io_connect_t uConnection = g_uConnection; + RTFILE hFile = g_File; + g_uConnection = 0; + g_File = NIL_RTFILE; + kern_return_t kr = IOServiceClose(uConnection); + AssertMsg(kr == kIOReturnSuccess, ("%#x (%d)\n", kr, kr)); + int rc = RTFileClose(hFile); + AssertRC(rc); + # else /* The IPRT case. */ RTFILE File = g_File; g_File = NIL_RTFILE; @@ -357,7 +410,7 @@ int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData) } return VINF_SUCCESS; -#elif defined(RT_OS_LINUX) +#elif defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) # ifdef VBOX_VBGLR3_XFREE86 int rc = xf86ioctl((int)g_File, iFunction, pvData); # else @@ -380,6 +433,20 @@ int vbglR3DoIOCtl(unsigned iFunction, void *pvData, size_t cbData) NOREF(cbData); return rc; +#elif defined(RT_OS_HAIKU) + /* The ioctl hook in Haiku does take the len parameter when specified, + * so just use it. */ + int rc = ioctl((int)g_File, iFunction, pvData, cbData); + if (RT_LIKELY(rc == 0)) + return VINF_SUCCESS; + + /* Positive values are negated VBox error status codes. */ + if (rc > 0) + rc = -rc; + else + rc = RTErrConvertFromErrno(errno); + return rc; + #elif defined(VBOX_VBGLR3_XFREE86) /* PORTME - This is preferred over the RTFileIOCtl variant below, just be careful with the (int). */ /** @todo test status code passing! */ |