ssize_t fatfs_write(file_t * file, struct uio * uio, size_t count) { void * buf; struct fatfs_inode * in = get_inode_of_vnode(file->vnode); size_t count_out; int err; if (!S_ISREG(file->vnode->vn_mode)) return -EOPNOTSUPP; err = f_lseek(&in->fp, file->seek_pos); if (err) return -EIO; err = uio_get_kaddr(uio, &buf); if (err) return err; err = f_write(&in->fp, buf, count, &count_out); if (err) return fresult2errno(err); file->seek_pos = f_tell(&in->fp); return count_out; }
/** * Override read() function. */ static ssize_t procfs_read(file_t * file, struct uio * uio, size_t bcount) { const struct procfs_info * spec = PROCFS_GET_FILESPEC(file); struct procfs_stream * stream; void * vbuf; ssize_t bytes; int err; if (!spec || spec->ftype > PROCFS_LAST || !file->stream) return -EIO; err = uio_get_kaddr(uio, &vbuf); if (err) return err; stream = (struct procfs_stream *)file->stream; bytes = stream->bytes; if (bytes > 0 && file->seek_pos <= bytes) { const ssize_t count = min(bcount, bytes - file->seek_pos); if (count <= bytes) { ssize_t sz; sz = strlcpy((char *)vbuf, stream->buf + file->seek_pos, count); sz++; bytes = (sz >= count) ? count : sz; file->seek_pos += bytes; } } return bytes; }
ssize_t dev_write(file_t * file, struct uio * uio, size_t bcount) { vnode_t * const vnode = file->vnode; const off_t offset = file->seek_pos; const int oflags = file->oflags; struct dev_info * devnfo = (struct dev_info *)vnode->vn_specinfo; uint8_t * buf; size_t buf_offset; off_t block_offset; ssize_t bytes_wr; int err; if (!devnfo->write) return -EOPNOTSUPP; err = uio_get_kaddr(uio, (void **)(&buf)); if (err) return err; if ((devnfo->flags & DEV_FLAGS_MB_WRITE) && ((bcount / devnfo->block_size) > 1)) { return devnfo->write(devnfo, offset, buf, bcount, oflags); } buf_offset = 0; block_offset = 0; do { int tries = RW_MAX_TRIES; size_t to_write = (bcount > devnfo->block_size) ? devnfo->block_size : bcount; ssize_t ret; while (1) { ret = devnfo->write(devnfo, offset + block_offset, &buf[buf_offset], to_write, oflags); if (ret < 0 && --tries <= 0) { bytes_wr = (buf_offset > 0) ? buf_offset : ret; goto out; } else { break; } } buf_offset += ret; block_offset++; bcount -= ret; } while (bcount > 0); bytes_wr = buf_offset; out: file->seek_pos += bytes_wr; return bytes_wr; }
/** * Override write() function. */ static ssize_t procfs_write(file_t * file, struct uio * uio, size_t bcount) { const struct procfs_info * spec = PROCFS_GET_FILESPEC(file); procfs_writefn_t * fn; void * vbuf; int err; if (!spec) return -EIO; if (spec->ftype > PROCFS_LAST) return -ENOLINK; fn = procfs_write_funcs[spec->ftype]; if (!fn) return -ENOTSUP; err = uio_get_kaddr(uio, &vbuf); if (err) return err; return fn(spec, (struct procfs_stream *)(file->stream), vbuf, bcount); }