error_t _hurd_fd_read (struct hurd_fd *fd, void *buf, size_t *nbytes, loff_t offset) { error_t err; char *data; mach_msg_type_number_t nread; error_t readfd (io_t port) { return __io_read (port, &data, &nread, offset, *nbytes); } data = buf; nread = *nbytes; if (err = HURD_FD_PORT_USE (fd, _hurd_ctty_input (port, ctty, readfd))) return err; if (data != buf) { if (nread > *nbytes) /* Sanity check for bogus server. */ { __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); return EGRATUITOUS; } memcpy (buf, data, nread); __vm_deallocate (__mach_task_self (), (vm_address_t) data, nread); } *nbytes = nread; return 0; }
error_t _hurd_fd_write (struct hurd_fd *fd, const void *buf, size_t *nbytes, loff_t offset) { error_t err; mach_msg_type_number_t wrote; error_t writefd (io_t port) { return __io_write (port, buf, *nbytes, offset, &wrote); } err = HURD_FD_PORT_USE (fd, _hurd_ctty_output (port, ctty, writefd)); if (! err) *nbytes = wrote; return err; }
/* Read a directory entry from DIRP. */ struct dirent64 * __readdir64 (DIR *dirp) { struct dirent64 *dp; if (dirp == NULL) { errno = EINVAL; return NULL; } __libc_lock_lock (dirp->__lock); do { if (dirp->__ptr - dirp->__data >= dirp->__size) { /* We've emptied out our buffer. Refill it. */ char *data = dirp->__data; int nentries; error_t err; if (err = HURD_FD_PORT_USE (dirp->__fd, __dir_readdir (port, &data, &dirp->__size, dirp->__entry_ptr, -1, 0, &nentries))) { __hurd_fail (err); dp = NULL; break; } /* DATA now corresponds to entry index DIRP->__entry_ptr. */ dirp->__entry_data = dirp->__entry_ptr; if (data != dirp->__data) { /* The data was passed out of line, so our old buffer is no longer useful. Deallocate the old buffer and reset our information for the new buffer. */ __vm_deallocate (__mach_task_self (), (vm_address_t) dirp->__data, dirp->__allocation); dirp->__data = data; dirp->__allocation = round_page (dirp->__size); } /* Reset the pointer into the buffer. */ dirp->__ptr = dirp->__data; if (nentries == 0) { /* End of file. */ dp = NULL; break; } /* We trust the filesystem to return correct data and so we ignore NENTRIES. */ } dp = (struct dirent64 *) dirp->__ptr; dirp->__ptr += dp->d_reclen; ++dirp->__entry_ptr; /* Loop to ignore deleted files. */ } while (dp->d_fileno == 0); __libc_lock_unlock (dirp->__lock); return dp; }