Merge pull request #2543 from ermshiperete/Xamarin-31021
[mono.git] / support / serial.c
index 77eee9fdbeeeeea643efdd312617eeaad27e71c2..ec02e48b5e8bd37a30601aa90c5332e9bcfecba1 100644 (file)
@@ -21,7 +21,7 @@
 #include <sys/ioctl.h>
 
 /* This is for ASYNC_*, serial_struct on linux */
-#if defined(__linux__)
+#if defined(HAVE_LINUX_SERIAL_H)
 #include <linux/serial.h>
 #endif
 
 #endif
 
 /* sys/time.h (for timeval) is required when using osx 10.3 (but not 10.4) */
-#ifdef __APPLE__
+/* IOKit is a private framework in iOS, so exclude there */
+#if defined(__APPLE__) && !defined(HOST_IOS) && !defined(HOST_WATCHOS) && !defined(HOST_APPLETVOS)
+#define HAVE_IOKIT 1
+#endif
+
+#if defined(HAVE_IOKIT)
 #include <sys/time.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/serial/IOSerialKeys.h>
+#include <IOKit/serial/ioss.h>
+#include <IOKit/IOBSD.h>
 #endif
 
 /* This is a copy of System.IO.Ports.Handshake */
@@ -379,18 +388,24 @@ set_attributes (int fd, int baud_rate, MonoParity parity, int dataBits, MonoStop
                if (cfsetospeed (&newtio, baud_rate) < 0 || cfsetispeed (&newtio, baud_rate) < 0)
                        return FALSE;
        } else {
-               /* On Linux, to set a custom baud rate, we must set the "standard" baud_rate
-                * to 38400.
+#if __linux__ || defined(HAVE_IOKIT)
+
+               /* On Linux to set a custom baud rate, we must set the
+                * "standard" baud_rate to 38400.   On Apple we set it purely
+                * so that tcsetattr has something to use (and report back later), but
+                * the Apple specific API is still opaque to these APIs, see:
+                * https://developer.apple.com/library/mac/samplecode/SerialPortSample/Listings/SerialPortSample_SerialPortSample_c.html#//apple_ref/doc/uid/DTS10000454-SerialPortSample_SerialPortSample_c-DontLinkElementID_4
                 */
                if (cfsetospeed (&newtio, B38400) < 0 || cfsetispeed (&newtio, B38400) < 0)
                        return FALSE;
+#endif
        }
 
        if (tcsetattr (fd, TCSANOW, &newtio) < 0)
                return FALSE;
 
        if (custom_baud_rate == TRUE){
-#if defined(__linux__)
+#if defined(HAVE_LINUX_SERIAL_H)
                struct serial_struct ser;
 
                if (ioctl (fd, TIOCGSERIAL, &ser) < 0)
@@ -406,6 +421,10 @@ set_attributes (int fd, int baud_rate, MonoParity parity, int dataBits, MonoStop
                {
                        return FALSE;
                }
+#elif defined(HAVE_IOKIT)
+               speed_t speed = baud_rate;
+               if (ioctl(fd, IOSSIOSPEED, &speed) == -1)
+                       return FALSE;
 #else
                /* Don't know how to set custom baud rate on this platform. */
                return FALSE;