fssh_ssize_t _kern_write(int fd, fssh_off_t pos, const void *buffer, fssh_size_t length) { struct file_descriptor *descriptor; fssh_ssize_t bytesWritten; descriptor = get_fd(get_current_io_context(true), fd); if (descriptor == NULL) return FSSH_B_FILE_ERROR; if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) { put_fd(descriptor); return FSSH_B_FILE_ERROR; } if (pos == -1) pos = descriptor->pos; if (descriptor->ops->fd_write) { bytesWritten = descriptor->ops->fd_write(descriptor, pos, buffer, &length); if (bytesWritten >= FSSH_B_OK) { if (length > FSSH_SSIZE_MAX) bytesWritten = FSSH_SSIZE_MAX; else bytesWritten = (fssh_ssize_t)length; descriptor->pos = pos + length; } } else bytesWritten = FSSH_B_BAD_VALUE; put_fd(descriptor); return bytesWritten; }
ssize_t _kern_read_dir(int fd, struct dirent* buffer, size_t bufferSize, uint32 maxCount) { struct file_descriptor* descriptor; ssize_t retval; TRACE(("sys_read_dir(fd = %d, buffer = %p, bufferSize = %ld, count = " "%lu)\n",fd, buffer, bufferSize, maxCount)); struct io_context* ioContext = get_current_io_context(true); descriptor = get_fd(ioContext, fd); if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0) return B_FILE_ERROR; if (descriptor->ops->fd_read_dir) { uint32 count = maxCount; retval = descriptor->ops->fd_read_dir(ioContext, descriptor, buffer, bufferSize, &count); if (retval >= 0) retval = count; } else retval = B_UNSUPPORTED; put_fd(descriptor); return retval; }
void fdclose(struct fgrp *f, int fd) { int i; struct chan *c; spin_lock(&f->lock); if (f->closed) { spin_unlock(&f->lock); return; } c = f->fd[fd]; if (c == 0) { /* can happen for users with shared fd tables */ spin_unlock(&f->lock); return; } f->fd[fd] = 0; if (fd == f->maxfd) for (i = fd; --i >= 0 && f->fd[i] == 0;) f->maxfd = i; if (fd < f->minfd) f->minfd = fd; /* VFS hack: give the FD back to VFS */ put_fd(¤t->open_files, fd); spin_unlock(&f->lock); cclose(c); }
static int dup_fd(int fd, bool kernel) { struct io_context* context = get_current_io_context(kernel); struct file_descriptor* descriptor; int status; TRACE(("dup_fd: fd = %d\n", fd)); // Try to get the fd structure descriptor = get_fd(context, fd); if (descriptor == NULL) return B_FILE_ERROR; // now put the fd in place status = new_fd(context, descriptor); if (status < 0) put_fd(descriptor); else { mutex_lock(&context->io_mutex); fd_set_close_on_exec(context, status, false); mutex_unlock(&context->io_mutex); } return status; }
/*! POSIX says this should be the same as: close(newfd); fcntl(oldfd, F_DUPFD, newfd); We do dup2() directly to be thread-safe. */ static int dup2_fd(int oldfd, int newfd, bool kernel) { struct file_descriptor* evicted = NULL; struct io_context* context; TRACE(("dup2_fd: ofd = %d, nfd = %d\n", oldfd, newfd)); // quick check if (oldfd < 0 || newfd < 0) return B_FILE_ERROR; // Get current I/O context and lock it context = get_current_io_context(kernel); mutex_lock(&context->io_mutex); // Check if the fds are valid (mutex must be locked because // the table size could be changed) if ((uint32)oldfd >= context->table_size || (uint32)newfd >= context->table_size || context->fds[oldfd] == NULL || (context->fds[oldfd]->open_mode & O_DISCONNECTED) != 0) { mutex_unlock(&context->io_mutex); return B_FILE_ERROR; } // Check for identity, note that it cannot be made above // because we always want to return an error on invalid // handles select_info* selectInfos = NULL; if (oldfd != newfd) { // Now do the work TFD(Dup2FD(context, oldfd, newfd)); evicted = context->fds[newfd]; selectInfos = context->select_infos[newfd]; context->select_infos[newfd] = NULL; atomic_add(&context->fds[oldfd]->ref_count, 1); atomic_add(&context->fds[oldfd]->open_count, 1); context->fds[newfd] = context->fds[oldfd]; if (evicted == NULL) context->num_used_fds++; } fd_set_close_on_exec(context, newfd, false); mutex_unlock(&context->io_mutex); // Say bye bye to the evicted fd if (evicted) { deselect_select_infos(evicted, selectInfos, true); close_fd(evicted); put_fd(evicted); } return newfd; }
bool fd_is_valid(int fd, bool kernel) { struct file_descriptor *descriptor = get_fd(get_current_io_context(kernel), fd); if (descriptor == NULL) return false; put_fd(descriptor); return true; }
fssh_ssize_t _kern_writev(int fd, fssh_off_t pos, const fssh_iovec *vecs, fssh_size_t count) { struct file_descriptor *descriptor; fssh_ssize_t bytesWritten = 0; fssh_status_t status; uint32_t i; descriptor = get_fd(get_current_io_context(true), fd); if (!descriptor) return FSSH_B_FILE_ERROR; if ((descriptor->open_mode & FSSH_O_RWMASK) == FSSH_O_RDONLY) { put_fd(descriptor); return FSSH_B_FILE_ERROR; } if (pos == -1) pos = descriptor->pos; if (descriptor->ops->fd_write) { for (i = 0; i < count; i++) { fssh_size_t length = vecs[i].iov_len; status = descriptor->ops->fd_write(descriptor, pos, vecs[i].iov_base, &length); if (status < FSSH_B_OK) { bytesWritten = status; break; } if ((uint32_t)bytesWritten + length > FSSH_SSIZE_MAX) bytesWritten = FSSH_SSIZE_MAX; else bytesWritten += (fssh_ssize_t)length; pos += vecs[i].iov_len; } } else bytesWritten = FSSH_B_BAD_VALUE; descriptor->pos = pos; put_fd(descriptor); return bytesWritten; }
/*! This function checks if the specified fd is valid in the current context. It can be used for a quick check; the fd is not locked so it could become invalid immediately after this check. */ bool fd_is_valid(int fd, bool kernel) { struct file_descriptor* descriptor = get_fd(get_current_io_context(kernel), fd); if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0) return false; put_fd(descriptor); return true; }
status_t close_fd_index(struct io_context* context, int fd) { struct file_descriptor* descriptor = remove_fd(context, fd); if (descriptor == NULL) return B_FILE_ERROR; close_fd(descriptor); put_fd(descriptor); // the reference associated with the slot return B_OK; }
static int vm_mmap_out(struct trace_proc * proc, const message * m_out) { if (m_out->m_mmap.flags & MAP_THIRDPARTY) put_endpoint(proc, "forwhom", m_out->m_mmap.forwhom); put_ptr(proc, "addr", (vir_bytes)m_out->m_mmap.addr); put_value(proc, "len", "%zu", m_out->m_mmap.len); put_flags(proc, "prot", mmap_prot, COUNT(mmap_prot), "0x%x", m_out->m_mmap.prot); put_flags(proc, "flags", mmap_flags, COUNT(mmap_flags), "0x%x", m_out->m_mmap.flags); put_fd(proc, "fd", m_out->m_mmap.fd); put_value(proc, "offset", "%"PRId64, m_out->m_mmap.offset); return CT_DONE; }
off_t _kern_seek(int fd, off_t pos, int seekType) { struct file_descriptor* descriptor; descriptor = get_fd(get_current_io_context(true), fd); if (!descriptor) return B_FILE_ERROR; if (descriptor->ops->fd_seek) pos = descriptor->ops->fd_seek(descriptor, pos, seekType); else pos = ESPIPE; put_fd(descriptor); return pos; }
static status_t get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor) { if (fd < 0) return EBADF; descriptor = get_fd(get_current_io_context(kernel), fd); if (descriptor == NULL) return EBADF; if (descriptor->type != FDTYPE_SOCKET) { put_fd(descriptor); return ENOTSOCK; } return B_OK; }
static status_t fd_ioctl(bool kernelFD, int fd, ulong op, void* buffer, size_t length) { struct file_descriptor* descriptor; int status; descriptor = get_fd(get_current_io_context(kernelFD), fd); if (descriptor == NULL) return B_FILE_ERROR; if (descriptor->ops->fd_ioctl) status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length); else status = EOPNOTSUPP; put_fd(descriptor); return status; }
fssh_status_t _kern_ioctl(int fd, uint32_t op, void *buffer, fssh_size_t length) { struct file_descriptor *descriptor; int status; TRACE(("sys_ioctl: fd %d\n", fd)); descriptor = get_fd(get_current_io_context(true), fd); if (descriptor == NULL) return FSSH_B_FILE_ERROR; if (descriptor->ops->fd_ioctl) status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length); else status = FSSH_EOPNOTSUPP; put_fd(descriptor); return status; }
status_t _user_rewind_dir(int fd) { struct file_descriptor* descriptor; status_t status; TRACE(("user_rewind_dir(fd = %d)\n", fd)); descriptor = get_fd(get_current_io_context(false), fd); if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0) return B_FILE_ERROR; if (descriptor->ops->fd_rewind_dir != NULL) status = descriptor->ops->fd_rewind_dir(descriptor); else status = B_UNSUPPORTED; put_fd(descriptor); return status; }
static fssh_status_t common_close(int fd, bool kernel) { struct io_context *io = get_current_io_context(kernel); struct file_descriptor *descriptor = remove_fd(io, fd); if (descriptor == NULL) return FSSH_B_FILE_ERROR; #ifdef TRACE_FD if (!kernel) TRACE(("_user_close(descriptor = %p)\n", descriptor)); #endif close_fd(descriptor); put_fd(descriptor); // the reference associated with the slot return FSSH_B_OK; }
fssh_status_t _kern_rewind_dir(int fd) { struct file_descriptor *descriptor; fssh_status_t status; TRACE(("sys_rewind_dir(fd = %d)\n",fd)); descriptor = get_fd(get_current_io_context(true), fd); if (descriptor == NULL) return FSSH_B_FILE_ERROR; if (descriptor->ops->fd_rewind_dir) status = descriptor->ops->fd_rewind_dir(descriptor); else status = FSSH_EOPNOTSUPP; put_fd(descriptor); return status; }
status_t _user_rewind_dir(int fd) { struct file_descriptor* descriptor; status_t status; TRACE(("user_rewind_dir(fd = %d)\n", fd)); descriptor = get_fd(get_current_io_context(false), fd); if (descriptor == NULL) return B_FILE_ERROR; if (descriptor->ops->fd_rewind_dir) status = descriptor->ops->fd_rewind_dir(descriptor); else status = EOPNOTSUPP; put_fd(descriptor); return status; }
off_t _user_seek(int fd, off_t pos, int seekType) { syscall_64_bit_return_value(); struct file_descriptor* descriptor; descriptor = get_fd(get_current_io_context(false), fd); if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0) return B_FILE_ERROR; TRACE(("user_seek(descriptor = %p)\n", descriptor)); if (descriptor->ops->fd_seek != NULL) pos = descriptor->ops->fd_seek(descriptor, pos, seekType); else pos = ESPIPE; put_fd(descriptor); return pos; }
static status_t fd_ioctl(bool kernelFD, int fd, uint32 op, void* buffer, size_t length) { struct file_descriptor* descriptor; int status; descriptor = get_fd(get_current_io_context(kernelFD), fd); if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0) return B_FILE_ERROR; if (descriptor->ops->fd_ioctl != NULL) status = descriptor->ops->fd_ioctl(descriptor, op, buffer, length); else status = B_DEV_INVALID_IOCTL; if (status == B_DEV_INVALID_IOCTL) status = ENOTTY; put_fd(descriptor); return status; }
static status_t do_iterative_fd_io_finish(void* _cookie, io_request* request, status_t status, bool partialTransfer, generic_size_t transferEndOffset) { iterative_io_cookie* cookie = (iterative_io_cookie*)_cookie; if (cookie->finished != NULL) { cookie->finished(cookie->cookie, request, status, partialTransfer, transferEndOffset); } put_fd(cookie->descriptor); if (cookie->next_finished_callback != NULL) { cookie->next_finished_callback(cookie->next_finished_cookie, request, status, partialTransfer, transferEndOffset); } delete cookie; return B_OK; }
fssh_ssize_t _kern_read_dir(int fd, struct fssh_dirent *buffer, fssh_size_t bufferSize, uint32_t maxCount) { struct file_descriptor *descriptor; fssh_ssize_t retval; TRACE(("sys_read_dir(fd = %d, buffer = %p, bufferSize = %ld, count = %lu)\n",fd, buffer, bufferSize, maxCount)); descriptor = get_fd(get_current_io_context(true), fd); if (descriptor == NULL) return FSSH_B_FILE_ERROR; if (descriptor->ops->fd_read_dir) { uint32_t count = maxCount; retval = descriptor->ops->fd_read_dir(descriptor, buffer, bufferSize, &count); if (retval >= 0) retval = count; } else retval = FSSH_EOPNOTSUPP; put_fd(descriptor); return retval; }
inline void Unlock(file_descriptor* lockable) { put_fd(lockable); }
~FDPutter() { if (descriptor != NULL) put_fd(descriptor); }