// Seek to a new position on a file descriptor. public static long __syscall_lseek(int fd, long offset, int whence) { // Get the stream and validate it. byte[] buffer; Stream stream = FileTable.GetStreamAndBuffer(fd, out buffer); if (stream == null) { return(-9); /* EBADF */ } else if (!stream.CanSeek) { return(-29); /* ESPIPE */ } // Validate the "whence" argument. if (whence < 0 || whence > 2) { return(-22); /* EINVAL */ } // Seek to the new position. We lock down the buffer // to synchronize descriptor accesses with pread/pwrite. try { lock (buffer) { return(stream.Seek(offset, (SeekOrigin)whence)); } } catch (NotSupportedException) { return(-29); /* ESPIPE */ } catch (ObjectDisposedException) { return(-9); /* EBADF */ } catch (EndOfStreamException) { return(-22); /* EINVAL */ } }
// Read data from a file descriptor. public static int __syscall_read(int fd, IntPtr buf, uint count) { // Get the stream and validate it. byte[] buffer; Stream stream = FileTable.GetStreamAndBuffer(fd, out buffer); if (stream == null) { return(-9); /* EBADF */ } else if (count == 0) { return(0); } else if (buf == IntPtr.Zero) { return(-14); /* EFAULT */ } // Read data from the stream. We lock down the buffer // to prevent other threads from accessing the stream // until we have finished with it. int result = 0; int templen; try { lock (buffer) { while (count > 0) { templen = buffer.Length; if (((uint)templen) > count) { templen = (int)count; } templen = stream.Read(buffer, 0, templen); if (templen > 0) { Marshal.Copy(buffer, 0, buf, templen); buf = new IntPtr(buf.ToInt64() + templen); result += templen; count -= (uint)templen; } else { break; } } } } catch (IOException) { return(-5); /* EIO */ } catch (ObjectDisposedException) { return(-9); /* EBADF */ } catch (NotSupportedException) { return(-22); /* EINVAL */ } catch (SocketException) { return(-11); /* EAGAIN */ } return(result); }