Beispiel #1
0
        public void SocketPair()
        {
            int socket1, socket2;

            if (Syscall.socketpair(UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            int r0 = Syscall.close(socket1);
            int r1 = Syscall.close(socket2);

            if (r0 < 0 || r1 < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
        }
Beispiel #2
0
        public void Dispose()
        {
            lock (lck) {
                if (fd != -1)
                {
                    int r;
                    // Don't retry close() on EINTR, on a lot of systems (e.g. Linux) the FD will be already closed when EINTR is returned, see https://lwn.net/Articles/576478/
                    r  = DBus.Unix.UnixSocket.close(fd);
                    fd = -1;

                    if (r < 0)
                    {
                        UnixMarshal.ThrowExceptionForLastError();
                    }
                }
            }
        }
Beispiel #3
0
        public void Close()
        {
            if (!_isOpen)
            {
                return;
            }

            int result = Syscall.close(_fileDescriptor);

            if (result < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            else
            {
                _isOpen = false;
            }
        }
Beispiel #4
0
        public void Shutdown()
        {
            WithSocketPair((so1, so2) => {
                if (Syscall.shutdown(so1, ShutdownOption.SHUT_WR) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                var buffer2 = new byte[1024];
                long ret    = Syscall.recv(so2, buffer2, (ulong)buffer2.Length, 0);
                if (ret < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                Assert.AreEqual(ret, 0);
            });
        }
Beispiel #5
0
        public static void TurnOffMacCaching(SafeFileHandle handle)
        {
            if (OS.OsFlavor != OsFlavor.MacOS)
            {
                return;
            }
#if __MonoCS__ || USE_UNIX_IO
            long r = 0;
            do
            {
                r = fcntl(handle.DangerousGetHandle().ToInt32(), MAC_F_NOCACHE, 1);
            } while (UnixMarshal.ShouldRetrySyscall((int)r));
            if (r == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
#endif
        }
Beispiel #6
0
        public unsafe uint PRead(SafeFileHandle handle, Span <byte> data, ulong position)
        {
            fixed(void *dataptr = data)
            {
                long result;

                do
                {
                    result = Mono.Unix.Native.Syscall.pread((int)handle.DangerousGetHandle(), dataptr,
                                                            (ulong)data.Length, (long)position);
                } while (UnixMarshal.ShouldRetrySyscall((int)result));

                if (result == -1)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                return((uint)result);
            }
        }
Beispiel #7
0
        public static void Disable(SafeFileHandle handle)
        {
            if (!Runtime.IsMacOS)
            {
                return;
            }

            long r;

            do
            {
                r = fcntl(handle.DangerousGetHandle().ToInt32(), MAC_F_NOCACHE, 1);
            } while (UnixMarshal.ShouldRetrySyscall((int)r));

            if (r == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
        }
Beispiel #8
0
    public UnixFD GetFD(DisposableList disposableList, bool throwError)
    {
        var fd_ = Syscall.open("/dev/null", OpenFlags.O_RDWR, 0);

        if (fd_ < 0)
        {
            UnixMarshal.ThrowExceptionForLastError();
        }
        var fd = new UnixFD(fd_);

        disposableList.Add(fd);

        if (throwError)
        {
            throw new Exception("Throwing an exception after creating a UnixFD object");
        }

        return(fd);
    }
Beispiel #9
0
        public long Read(byte[] buffer, ulong count)
        {
            long bytesRead;

            unsafe
            {
                fixed(byte *b = buffer)
                {
                    bytesRead = Syscall.read(_fileDescriptor, b, count);
                }
            }

            if (bytesRead < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            return(bytesRead);
        }
Beispiel #10
0
        public long Write(byte[] buffer, ulong count)
        {
            long bytesWritten;

            unsafe
            {
                fixed(byte *b = buffer)
                {
                    bytesWritten = Syscall.write(_fileDescriptor, b, count);
                }
            }

            if (bytesWritten < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            return(bytesWritten);
        }
Beispiel #11
0
        public void Open()
        {
            if (_isOpen)
            {
                return;
            }

            int fd = Syscall.open(_fileName, OpenFlags.O_RDWR);

            if (fd < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            else
            {
                _isOpen         = true;
                _fileDescriptor = fd;
            }
        }
Beispiel #12
0
        internal static int Open(string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access)
        {
            if (MonoUtil.IsUnix)
            {
                Stat buf;
                if (Syscall.stat(path, out buf) == -1)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                if (capacity == 0)
                {
                    // Special files such as FIFOs, sockets, and devices can
                    // have a size of 0. Specifying a capacity for these
                    // also makes little sense, so don't do the check if the
                    // file is one of these.
                    if (buf.st_size == 0 &&
                        (buf.st_mode & (FilePermissions.S_IFCHR |
                                        FilePermissions.S_IFBLK |
                                        FilePermissions.S_IFIFO |
                                        FilePermissions.S_IFSOCK)) == 0)
                    {
                        throw new ArgumentException("A positive capacity must be specified for a Memory Mapped File backed by an empty file.");
                    }

                    capacity = buf.st_size;
                }
                else if (capacity < buf.st_size)
                {
                    throw new ArgumentException("The capacity may not be smaller than the file size.");
                }

                int fd = Syscall.open(path, ToUnixMode(mode) | ToUnixMode(access), FilePermissions.DEFFILEMODE);

                if (fd == -1)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                return(fd);
            }

            throw new NotImplementedException();
        }
Beispiel #13
0
        public override unsafe int Read(byte[] buffer, int offset, int length)
        {
            AssertValidBuffer(buffer, offset, length);

            long r = 0;

            fixed(byte *buf = buffer)
            {
                do
                {
                    r = Syscall.read(fd, buf + offset, (ulong)length);
                } while (UnixMarshal.ShouldRetrySyscall((int)r));
                if (r < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                return((int)r);
            }
        }
Beispiel #14
0
        public void SockOpt()
        {
            WithSockets(UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
                if (Syscall.getsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, out value) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(0, value);

                // Set SO_REUSEADDR to 1
                if (Syscall.setsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, 1) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                // Get and check SO_REUSEADDR
                int value;
                if (Syscall.getsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, out value) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreNotEqual(0, value);

                // Set SO_REUSEADDR to 0
                if (Syscall.setsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, new byte[10], 4) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                // Get and check SO_REUSEADDR
                var buffer = new byte[15];
                long size  = 12;
                if (Syscall.getsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, buffer, ref size) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(size, 4);
                for (int i = 0; i < size; i++)
                {
                    Assert.AreEqual(buffer[i], 0);
                }
            });
        }
Beispiel #15
0
        public void ReadlinkMultiByteChar()
        {
            string link = UnixPath.Combine(TempFolder, "link");

            CreateLink("á");

            var sb  = new StringBuilder(2);
            int res = Syscall.readlink(link, sb);

            if (res < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            Assert.AreEqual(res, 2);
            Assert.AreEqual(sb.Length, 2);
            Assert.AreEqual(sb.Capacity, 2);
            Assert.AreEqual(sb.ToString(), "á\u0000");
        }
Beispiel #16
0
        public static void Seek(SafeFileHandle handle, long position, SeekOrigin origin)
        {
#if !__MonoCS__ && !USE_UNIX_IO
            var low  = (int)(position & 0xffffffff);
            var high = (int)(position >> 32);
            var f    = WinNative.SetFilePointer(handle, low, out high, WinNative.EMoveMethod.Begin);
            if (f == WinNative.INVALID_SET_FILE_POINTER)
            {
                throw new Win32Exception();
            }
#else
            int r = 0;
            do
            {
                r = (int)Syscall.lseek(handle.DangerousGetHandle().ToInt32(), position, SeekFlags.SEEK_SET);
            } while (UnixMarshal.ShouldRetrySyscall(r));
            UnixMarshal.ThrowExceptionForLastErrorIf(r);
#endif
        }
Beispiel #17
0
        public unsafe byte[] getReportDescriptor()
        {
            hidraw_report_descriptor *descriptor = stackalloc hidraw_report_descriptor[1];

            descriptor->size = (uint)ReportDescriptorSize;

            var ret = ioctl(fd, HIDIOCGRDESC, (IntPtr)descriptor);

            if (ret < 0)
            {
                var err = (Errno)(-ret);
                UnixMarshal.ThrowExceptionForError(err);
            }

            var bytes = new byte[descriptor->size];

            Marshal.Copy((IntPtr)descriptor->value, bytes, 0, ReportDescriptorSize);
            return(bytes);
        }
Beispiel #18
0
        private void OpenPty(string name)
        {
            var openFlags = OpenFlags.O_NOCTTY | OpenFlags.O_RDWR;

            /*if(nonBlocking)
             * {
             *  openFlags |= OpenFlags.O_NONBLOCK;
             * }*/

            master = Syscall.open(name, openFlags);
            UnixMarshal.ThrowExceptionForLastErrorIf(master);

            IntPtr termios = Marshal.AllocHGlobal(128); // termios struct is 60-bytes, but we allocate more just to make sure

            Tcgetattr(0, termios);
            Cfmakeraw(termios);
            Tcsetattr(master, 1, termios);  // 1 == TCSAFLUSH
            Marshal.FreeHGlobal(termios);
        }
Beispiel #19
0
        public static void SetFileSize(SafeFileHandle handle, long count)
        {
#if !__MonoCS__ && !USE_UNIX_IO
            var low  = (int)(count & 0xffffffff);
            var high = (int)(count >> 32);
            WinNative.SetFilePointer(handle, low, out high, WinNative.EMoveMethod.Begin);
            if (!WinNative.SetEndOfFile(handle))
            {
                throw new Win32Exception();
            }
#else
            int r;
            do
            {
                r = Syscall.ftruncate(handle.DangerousGetHandle().ToInt32(), count);
            } while (UnixMarshal.ShouldRetrySyscall(r));
            UnixMarshal.ThrowExceptionForLastErrorIf(r);
#endif
            FSync(handle);
        }
Beispiel #20
0
        public static long GetFileSize(SafeFileHandle handle)
        {
#if !__MonoCS__ && !USE_UNIX_IO
            long size = 0;
            if (!WinNative.GetFileSizeEx(handle, out size))
            {
                throw new Win32Exception();
            }
            return(size);
#else
            Stat s;
            int  r;
            do
            {
                r = (int)Syscall.fstat(handle.DangerousGetHandle().ToInt32(), out s);
            } while (UnixMarshal.ShouldRetrySyscall(r));
            UnixMarshal.ThrowExceptionForLastErrorIf(r);
            return(s.st_size);
#endif
        }
Beispiel #21
0
        public unsafe void PWrite(SafeFileHandle handle, ReadOnlySpan <byte> data, ulong position)
        {
            fixed(void *dataptr = data)
            {
                long result;

                do
                {
                    result = Mono.Unix.Native.Syscall.pwrite((int)handle.DangerousGetHandle(), dataptr,
                                                             (ulong)data.Length, (long)position);
                } while (UnixMarshal.ShouldRetrySyscall((int)result));

                if (result == -1)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                if (result != data.Length)
                {
                    throw new BTDBException($"Out of disk space written {result} out of {data.Length} at {position}");
                }
            }
        }
Beispiel #22
0
        public static byte[] ReadDataWithTimeout(int fd, int count, int timeout, Func <bool> shouldCancel)
        {
            int pollResult;
            var pollData = new Pollfd {
                fd     = fd,
                events = PollEvents.POLLIN
            };

            do
            {
                pollResult = Syscall.poll(new [] { pollData }, timeout);
            }while(UnixMarshal.ShouldRetrySyscall(pollResult) && !shouldCancel());

            if (pollResult > 0)
            {
                return(ReadData(fd, count));
            }
            else
            {
                return(null);
            }
        }
Beispiel #23
0
        void WithSocketPair(Action <int, int> f)
        {
            int socket1, socket2;

            if (Syscall.socketpair(UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            try {
                SetTimeout(socket1);
                SetTimeout(socket2);

                f(socket1, socket2);
            } finally {
                int r0 = Syscall.close(socket1);
                int r1 = Syscall.close(socket2);
                if (r0 < 0 || r1 < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
            }
        }
Beispiel #24
0
        static int Open(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }
            while (true)
            {
                var ret = open(path, OpenFlags.O_RDWR);
                if (ret == -1)
                {
                    var err = Stdlib.GetLastError();
                    if (err == Errno.EINTR)
                    {
                        continue;
                    }
                    UnixMarshal.ThrowExceptionForError(err);
                }

                return(ret);
            }
        }
Beispiel #25
0
        public void SockOptLinger()
        {
            WithSockets(UnixAddressFamily.AF_INET, UnixSocketType.SOCK_STREAM, UnixSocketProtocol.IPPROTO_TCP, (so1, so2) => {
                Linger linger = new Linger {
                    l_onoff  = 1,
                    l_linger = 42,
                };
                // Set SO_LINGER
                if (Syscall.setsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, linger) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }

                // Get and check SO_LINGER
                Linger value;
                if (Syscall.getsockopt(so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, out value) < 0)
                {
                    UnixMarshal.ThrowExceptionForLastError();
                }
                Assert.AreEqual(linger, value);
            });
        }
Beispiel #26
0
        /// <summary>
        /// Open a connection to the I2C bus.
        /// </summary>
        /// <exception cref="ObjectDisposedException">
        /// This instance has been disposed.
        /// </exception>
        /// <exception cref="IOException">
        /// Unable to open the bus connection.
        /// </exception>
        public void Open()
        {
            if (this._isDisposed)
            {
                throw new ObjectDisposedException("CyrusBuilt.MonoPi.IO.I2C.I2CBus");
            }

            if (this._isOpen)
            {
                return;
            }

            Int32 result = UnsafeNativeMethods.I2COpenBus(this._busPath);

            if (result < 0)
            {
                String errDesc = UnixMarshal.GetErrorDescription(Stdlib.GetLastError());
                throw new IOException("Error opening bus '" + this._busPath + "': " + errDesc);
            }

            this._busHandle = result;
            this._isOpen    = true;
        }
Beispiel #27
0
        public static int Read(SafeFileHandle handle, byte *buffer, int offset, int count)
        {
#if !__MonoCS__ && !USE_UNIX_IO
            var read = 0;

            if (!WinNative.ReadFile(handle, buffer, count, ref read, 0))
            {
                throw new Win32Exception();
            }
            return(read);
#else
            int r;
            do
            {
                r = (int)Syscall.read(handle.DangerousGetHandle().ToInt32(), buffer, (ulong)count);
            } while (UnixMarshal.ShouldRetrySyscall((int)r));
            if (r == -1)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            return(count);
#endif
        }
Beispiel #28
0
        public override unsafe void Write(byte[] buffer, int offset, int length)
        {
            AssertValidBuffer(buffer, offset, length);

            int  pos = 0;
            long r   = 0;

            fixed(byte *buf = buffer)
            {
                while (pos < length)
                {
                    do
                    {
                        r = Syscall.write(fd, buf + offset + pos, (ulong)length);
                    } while (UnixMarshal.ShouldRetrySyscall((int)r));
                    if (r < 0)
                    {
                        UnixMarshal.ThrowExceptionForLastError();
                    }
                    pos += (int)r;
                }
            }
        }
Beispiel #29
0
        public void WriteBytes(int address, byte[] bytes)
        {
            log.Trace("Writing to I2C. Bus handle {0}", busHandle);
            var res = I2CNativeLib.WriteBytes(busHandle, address, bytes, bytes.Length);

            if (res == -1)
            {
                string message = String.Format(
                    "Error accessing address '{0}': {1}",
                    address,
                    UnixMarshal.GetErrorDescription(Stdlib.GetLastError()));

                log.Error(message);
                throw new IOException(message);
            }

            if (res == -2)
            {
                var message = String.Format("Error writing to address '{0}': I2C transaction failed", address);
                log.Error(message);
                throw new IOException(message);
            }
        }
Beispiel #30
0
        public void readlinkat_char()
        {
            if (!HaveReadlinkAt)
            {
                return;
            }

            foreach (string s in Targets)
            {
                CreateLink(s);

                var sb = new StringBuilder(256);
                do
                {
                    int oldCapacity = sb.Capacity;
                    int r           = Syscall.readlinkat(TempFD, "link", sb);
                    Assert.AreEqual(oldCapacity, sb.Capacity);
                    if (r < 0)
                    {
                        UnixMarshal.ThrowExceptionForLastError();
                    }
                    Assert.AreEqual(r, sb.Length);
                    Assert.GreaterOrEqual(sb.Capacity, r);
                    if (r == sb.Capacity)
                    {
                        checked { sb.Capacity *= 2; }
                    }
                    else
                    {
                        break;
                    }
                } while (true);
                var target = sb.ToString();

                Assert.AreEqual(s, target);
            }
        }