public static DateTime GetPreciseLastWriteTimeUtc(string path) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } var statOut = new Stat(); int statRet = Syscall.stat(path, out statOut); if (statRet == -1) { var errno = Syscall.GetLastError(); if (errno == Errno.ESRCH || errno == Errno.ENOTDIR || errno == Errno.ENOENT) { return(DateTime.MinValue); } UnixMarshal.ThrowExceptionForError(errno); } var result = NativeConvert.UnixEpoch.AddSeconds(statOut.st_mtime); // If this platform supports nanosecs // precision, take it into account. if (statOut.st_mtime_nsec != default(long)) { var ns = (double)statOut.st_mtime_nsec; result = result.AddSeconds(ns / 1000000000d); } return(result); }
int getReportDescriptorSize() { var ret = ioctl(fd, HIDIOCGRDESCSIZE, out int size); if (ret < 0) { var err = (Errno)(-ret); UnixMarshal.ThrowExceptionForError(err); } return(size); }
unsafe string getPhysicalLocation() { const int size = 256; byte *buf = stackalloc byte[size]; var ret = ioctl(fd, HIDIOCGRAWPHYS(size), (IntPtr)buf); if (ret < 0) { var err = (Errno)(-ret); UnixMarshal.ThrowExceptionForError(err); } return(Marshal.PtrToStringAnsi((IntPtr)buf)); }
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); }
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); } }
public void ThrowExceptionForError_Throws() { Assert.Throws <ArgumentException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EBADF)); Assert.Throws <ArgumentException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EINVAL)); Assert.Throws <ArgumentOutOfRangeException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ERANGE)); Assert.Throws <DirectoryNotFoundException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENOTDIR)); Assert.Throws <FileNotFoundException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENOENT)); Assert.Throws <InvalidOperationException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EOPNOTSUPP)); Assert.Throws <InvalidOperationException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EOPNOTSUPP)); Assert.Throws <InvalidOperationException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EPERM)); Assert.Throws <InvalidProgramException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENOEXEC)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EIO)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENOSPC)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENOTEMPTY)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENXIO)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EROFS)); Assert.Throws <IOException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ESPIPE)); Assert.Throws <NullReferenceException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EFAULT)); Assert.Throws <OverflowException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EOVERFLOW)); Assert.Throws <PathTooLongException>(() => UnixMarshal.ThrowExceptionForError(UnixError.ENAMETOOLONG)); Assert.Throws <UnauthorizedAccessException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EACCES)); Assert.Throws <UnauthorizedAccessException>(() => UnixMarshal.ThrowExceptionForError(UnixError.EISDIR)); Assert.Throws <Exception>(() => UnixMarshal.ThrowExceptionForError((UnixError)1234)); }
public IDisposable Connect() { if (monitor != null) { throw new InvalidOperationException("already connected"); } monitor = new Monitor(udev); monitor.AddMatchSubsystem("hidraw"); monitor.EnableReceiving(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; Task.Run(() => { try { var enumerator = new Enumerator(udev); enumerator.AddMatchSubsystem("hidraw"); enumerator.ScanDevices(); foreach (var device in enumerator) { if (token.IsCancellationRequested) { break; } var hids = TryGetHidDevices(device); if (hids == null) { continue; } foreach (var hid in hids) { subject.OnNext(hid); } } var pollfds = new Pollfd[] { new Pollfd { fd = monitor.Fd, events = PollEvents.POLLIN } }; while (!token.IsCancellationRequested) { // FIXME: it would be nice if we didn't wake up every 100ms // not sure how to interrupt a system call though // pinvoke pthread_kill() maybe? var ret = Syscall.poll(pollfds, 100); if (ret == -1) { var err = Stdlib.GetLastError(); if (err == Errno.EINTR) { continue; } UnixMarshal.ThrowExceptionForError(err); } if (token.IsCancellationRequested) { break; } if (ret == 0) { // timed out continue; } if (pollfds[0].revents.HasFlag(PollEvents.POLLNVAL)) { // monitor file descriptor is closed, monitor must // have been disposed, so complete gracefully break; } var device = monitor.TryReceiveDevice(); var hids = TryGetHidDevices(device); if (hids == null) { continue; } foreach (var hid in hids) { subject.OnNext(hid); } } subject.OnCompleted(); } catch (Exception ex) { subject.OnError(ex); } finally { monitor.Dispose(); monitor = null; } }, token); return(Disposable.Create(() => tokenSource.Cancel())); }