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 }
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(); } }
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); }
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 }
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); } }
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}"); } } }
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 }
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; } } }
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); } } }
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); } } }
// 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); } } }
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); } } }