Esempio n. 1
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);
            }
        }
        public static void Seek(SafeFileHandle handle, long position, SeekOrigin origin)
        {
#if !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
        }
Esempio n. 3
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();
            }
        }
Esempio n. 4
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);
        }
Esempio n. 5
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
        }
Esempio n. 6
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);
            }
        }
Esempio n. 7
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}");
                }
            }
        }
Esempio n. 8
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
        }
Esempio n. 9
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;
                }
            }
        }
Esempio n. 10
0
        protected override void OnOutput(BitwiseStream data)
        {
            if (Logger.IsDebugEnabled)
            {
                Logger.Debug("\n\n" + Utilities.HexDump(data));
            }

            long count = data.Length;
            //var buffer = new byte[MaxMTU];
            var buffer = new byte[CAN_MTU];
            int size   = data.Read(buffer, 0, buffer.Length);

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLOUT;

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLOUT) == 0)
                    {
                        continue;
                    }

                    //_socket.Write(buffer, 0, size);
                    _socket.Write(buffer, 0, CAN_MTU);

                    if (count != size)
                    {
                        throw new Exception(string.Format("Only sent {0} of {1} byte packet.", size, count));
                    }

                    return;
                }
                catch (Exception ex)
                {
                    Logger.Error("Unable to send CAN packet to {0}. {1}", Interface, ex.Message);

                    throw new SoftException(ex);
                }
            }
        }
Esempio n. 11
0
        protected override void OnInput()
        {
            System.Diagnostics.Debug.Assert(_socket != null);

            if (_recvBuffer == null || _recvBuffer.Capacity < _bufferSize)
            {
                _recvBuffer = new MemoryStream(_bufferSize);
            }

            _recvBuffer.Seek(0, SeekOrigin.Begin);
            _recvBuffer.SetLength(_recvBuffer.Capacity);

            byte[] buf    = _recvBuffer.GetBuffer();
            int    offset = (int)_recvBuffer.Position;
            int    size   = (int)_recvBuffer.Length;

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLIN;

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLIN) == 0)
                    {
                        continue;
                    }

                    var rxLen = _socket.Read(buf, offset, size);

                    _recvBuffer.SetLength(rxLen);

                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug("\n\n" + Utilities.HexDump(_recvBuffer));
                    }

                    // Got a valid packet
                    return;
                }
                catch (Exception ex)
                {
                    Logger.Error("Unable to receive CAN packet on {0}. {1}", Interface, ex.Message);

                    throw new SoftException(ex);
                }
            }
        }
Esempio n. 12
0
        // Send the two buffers and the FDs using sendmsg(), don't handle short writes
        // length1 + length2 must not be 0
        public unsafe long SendmsgShort(byte[] buffer1, long offset1, long length1,
                                        byte[] buffer2, long offset2, long length2,
                                        DBus.Protocol.UnixFDArray fds)
        {
            //Console.WriteLine ("SendmsgShort (X, {0}, {1}, {2}, {3}, {4}, {5})", offset1, length1, buffer2 == null ? "-" : "Y", offset2, length2, fds == null ? "-" : "" + fds.FDs.Count);
            AssertValidBuffer(buffer1, offset1, length1);
            if (buffer2 == null)
            {
                if (length2 != 0)
                {
                    throw new ArgumentOutOfRangeException("length2", "!= 0 while buffer2 == null");
                }
                offset2 = 0;
            }
            else
            {
                AssertValidBuffer(buffer2, offset2, length2);
            }

            fixed(byte *ptr1 = buffer1, ptr2 = buffer2)
            {
                var iovecs = new Iovec[] {
                    new Iovec {
                        iov_base = (IntPtr)(ptr1 + offset1),
                        iov_len  = (ulong)length1,
                    },
                    new Iovec {
                        iov_base = (IntPtr)(ptr2 + offset2),
                        iov_len  = (ulong)length2,
                    },
                };

                /* Simulate short writes
                 * if (iovecs[0].iov_len == 0) {
                 *      iovecs[1].iov_len = Math.Min (iovecs[1].iov_len, 5);
                 * } else {
                 *      iovecs[0].iov_len = Math.Min (iovecs[0].iov_len, 5);
                 *      iovecs[1].iov_len = 0;
                 * }
                 */
                byte[] cmsg = null;

                // Create copy of FDs to prevent the user from Dispose()ing the
                // FDs in another thread between writing the FDs into the cmsg
                // buffer and calling sendmsg()
                using (var fds2 = fds == null ? null : fds.Clone()) {
                    int fdCount = fds2 == null ? 0 : fds2.FDs.Count;
                    if (fdCount != 0)
                    {
                        // Create one SCM_RIGHTS control message
                        cmsg = new byte[Syscall.CMSG_SPACE((uint)fdCount * sizeof(int))];
                    }
                    var msghdr = new Msghdr {
                        msg_iov        = iovecs,
                        msg_iovlen     = length2 == 0 ? 1 : 2,
                        msg_control    = cmsg,
                        msg_controllen = cmsg == null ? 0 : cmsg.Length,
                    };
                    if (fdCount != 0)
                    {
                        var hdr = new Cmsghdr {
                            cmsg_len   = (long)Syscall.CMSG_LEN((uint)fdCount * sizeof(int)),
                            cmsg_level = UnixSocketProtocol.SOL_SOCKET,
                            cmsg_type  = UnixSocketControlMessage.SCM_RIGHTS,
                        };
                        hdr.WriteToBuffer(msghdr, 0);
                        var dataOffset = Syscall.CMSG_DATA(msghdr, 0);
                        fixed(byte *ptr = cmsg)
                        {
                            for (int i = 0; i < fdCount; i++)
                            {
                                ((int *)(ptr + dataOffset))[i] = fds2.FDs[i].Handle;
                            }
                        }
                    }
                    long r;
                    do
                    {
                        r = Syscall.sendmsg(fd, msghdr, MessageFlags.MSG_NOSIGNAL);
                    } while (UnixMarshal.ShouldRetrySyscall((int)r));
                    if (r < 0)
                    {
                        UnixMarshal.ThrowExceptionForLastError();
                    }
                    if (r == 0)
                    {
                        throw new Exception("sendmsg() returned 0");
                    }
                    return(r);
                }
            }
        }
Esempio n. 13
0
        protected override void OnOutput(byte[] buf, int offset, int count)
        {
            int size = count;

            Pollfd[] fds = new Pollfd[1];
            fds[0].fd     = _socket.Handle;
            fds[0].events = PollEvents.POLLOUT;

            if (Logger.IsDebugEnabled)
            {
                Logger.Debug("\n\n" + Utilities.HexDump(buf, offset, count));
            }

            int expires = Environment.TickCount + Timeout;
            int wait    = 0;

            for (;;)
            {
                try
                {
                    wait           = Math.Max(0, expires - Environment.TickCount);
                    fds[0].revents = 0;

                    int ret = Syscall.poll(fds, wait);

                    if (UnixMarshal.ShouldRetrySyscall(ret))
                    {
                        continue;
                    }

                    UnixMarshal.ThrowExceptionForLastErrorIf(ret);

                    if (ret == 0)
                    {
                        throw new TimeoutException();
                    }

                    if (ret != 1 || (fds[0].revents & PollEvents.POLLOUT) == 0)
                    {
                        continue;
                    }

                    _socket.Write(buf, offset, size);

                    return;
                }
                catch (Exception ex)
                {
                    if (ex is TimeoutException)
                    {
                        Logger.Debug("Ethernet packet not sent to {0} in {1}ms, timing out.", Interface, Timeout);
                    }
                    else
                    {
                        Logger.Error("Unable to send ethernet packet to {0}. {1}", Interface, ex.Message);
                    }

                    throw new SoftException(ex);
                }
            }
        }