int file_pipe(int fd[]) { int ret; struct file *file[2] = { NULL, NULL }; if ((ret = filemap_alloc(NO_FD, &file[0])) != 0) { goto failed_cleanup; } if ((ret = filemap_alloc(NO_FD, &file[1])) != 0) { goto failed_cleanup; } if ((ret = pipe_open(&(file[0]->node), &(file[1]->node))) != 0) { goto failed_cleanup; } file[0]->pos = 0; file[0]->readable = 1, file[0]->writable = 0; filemap_open(file[0]); file[1]->pos = 0; file[1]->readable = 0, file[1]->writable = 1; filemap_open(file[1]); fd[0] = file[0]->fd, fd[1] = file[1]->fd; return 0; failed_cleanup: if (file[0] != NULL) { filemap_free(file[0]); } if (file[1] != NULL) { filemap_free(file[1]); } return ret; }
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); }
void filemap_dup(struct file *to, struct file *from) { //kprintf("[filemap_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; filemap_open(to); }
int file_open(char *path, uint32_t open_flags) { bool readable = 0, writable = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: readable = 1; break; case O_WRONLY: writable = 1; break; case O_RDWR: readable = writable = 1; break; default: return -E_INVAL; } int ret; struct file *file; if ((ret = filemap_alloc(NO_FD, &file)) != 0) { return ret; } struct inode *node; if ((ret = vfs_open(path, open_flags, &node)) != 0) { filemap_free(file); return ret; } file->pos = 0; if (open_flags & O_APPEND) { struct stat __stat, *stat = &__stat; if ((ret = vop_fstat(node, stat)) != 0) { vfs_close(node); filemap_free(file); return ret; } file->pos = stat->st_size; } file->node = node; file->readable = readable; file->writable = writable; filemap_open(file); return file->fd; }
int file_mkfifo(const char *__name, uint32_t open_flags) { bool readonly = 0; switch (open_flags & O_ACCMODE) { case O_RDONLY: readonly = 1; case O_WRONLY: break; default: return -E_INVAL; } int ret; struct file *file; if ((ret = filemap_alloc(NO_FD, &file)) != 0) { return ret; } char *name; const char *device = readonly ? "pipe:r_" : "pipe:w_"; if ((name = stradd(device, __name)) == NULL) { ret = -E_NO_MEM; goto failed_cleanup_file; } if ((ret = vfs_open(name, open_flags, &(file->node))) != 0) { goto failed_cleanup_name; } file->pos = 0; file->readable = readonly, file->writable = !readonly; filemap_open(file); kfree(name); return file->fd; failed_cleanup_name: kfree(name); failed_cleanup_file: filemap_free(file); return ret; }