void dir_link(FS* fs, uint32_t parent, std::string const& name, uint32_t ino) { assert(fs); struct fail_sentry { inode* _inode; fail_sentry(inode* i) : _inode(i) { } ~fail_sentry() { if (_inode) fs_close_inode(_inode); } } sentry(fs_open_inode(fs, parent)); dir_link(sentry._inode, name, ino); }
/*! * \internal * TODO: write documentation. * Opens a file. */ file_handle* file_open(FS* fs, std::string const& path) { if (!fs) throw std::invalid_argument("file_open null arg: fs"); debug::tracer DT; DT << "opening file " << path; resolve_result rr = resolve_path(fs, path); if (rr.child.empty()) throw fs_error(ERROR_NOENTRY); uint32_t file_ino = 0; // Does it exist already or do we have to create it? // We open and lock the parent directory during this operation. { // block // FIXME: clean up this mess! open_inode parent(fs_open_inode(fs, rr.parent)); inode_guard parent_lock(parent->lock); bool found = try_dir_lookup(parent.get(), rr.child, file_ino); if (!found) { alloc_inode alloc_file_ino(fs, fs_alloc_inode(fs)); inode_data id; id.f_type = ITYPE_FILE; fs_write_inode(fs, alloc_file_ino, id); dir_link(parent.get(), rr.child, alloc_file_ino); file_ino = alloc_file_ino.release(); } } // block return file_open(fs, file_ino); }
Boolean shelf_link(String target, Boolean absolute) { return dir_link(shelfdir, target, absolute); }
Boolean cur_link(String target, Boolean absolute) { return dir_link(curdir, target, absolute); }