int vfs_open(char *path, uint32_t open_flags, struct inode **node_store) { bool can_write = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: break; case O_WRONLY: case O_RDWR: can_write = 1; break; default: return -E_INVAL; } if (open_flags & O_TRUNC) { if (!can_write) { return -E_INVAL; } } int ret; struct inode *dir, *node; if (open_flags & O_CREAT) { char *name; bool excl = (open_flags & O_EXCL) != 0; if ((ret = vfs_lookup_parent(path, &dir, &name)) != 0) { return ret; } ret = vop_create(dir, name, excl, &node); vop_ref_dec(dir); } else { ret = vfs_lookup(path, &node); } if (ret != 0) { return ret; } assert(node != NULL); if ((ret = vop_open(node, open_flags)) != 0) { vop_ref_dec(node); return ret; } vop_open_inc(node); if (open_flags & O_TRUNC) { if ((ret = vop_truncate(node, 0)) != 0) { vop_open_dec(node); vop_ref_dec(node); return ret; } } *node_store = node; return 0; }
void filemap_dup_close(struct file *to, struct file *from) { assert(to->status == FD_CLOSED && from->status == FD_CLOSED); to->pos = from->pos; to->readable = from->readable; to->writable = from->writable; struct inode *node = from->node; vop_ref_inc(node), vop_open_inc(node); to->node = node; }
void filemap_dup(struct file *to, struct file *from) { assert(to->status == FD_INIT && from->status == FD_OPENED); to->pos = from->pos; to->readable = from->readable; to->writable = from->writable; struct inode *node = from->node; vop_ref_inc(node), vop_open_inc(node); to->node = node; filemap_open(to); }
int pipe_open(struct inode **rnode_store, struct inode **wnode_store) { int ret; struct inode *root; if ((ret = vfs_get_root("pipe", &root)) != 0) { return ret; } ret = -E_NO_MEM; struct pipe_state *state; if ((state = pipe_state_create()) == NULL) { goto out; } struct fs *fs = vop_fs(root); struct inode *node[2] = { NULL, NULL }; if ((node[0] = pipe_create_inode(fs, NULL, state, 1)) == NULL) { goto failed_cleanup_state; } pipe_state_acquire(state); if ((node[1] = pipe_create_inode(fs, NULL, state, 0)) == NULL) { goto failed_cleanup_node0; } vop_open_inc(node[0]), vop_open_inc(node[1]); *rnode_store = node[0]; *wnode_store = node[1]; ret = 0; out: vop_ref_dec(root); return ret; failed_cleanup_node0: vop_ref_dec(node[0]); failed_cleanup_state: pipe_state_release(state); goto out; }
//fs_array_dup - duplicate file 'from' to file 'to' void fd_array_dup(struct file *to, struct file *from) { //cprintf("[fd_array_dup]from fd=%d, to fd=%d\n",from->fd, to->fd); assert(to->status == FD_INIT && from->status == FD_OPENED); to->pos = from->pos; to->readable = from->readable; to->writable = from->writable; struct inode *node = from->node; vop_ref_inc(node), vop_open_inc(node); to->node = node; fd_array_open(to); }