int chdir(const char *src) { int rv; struct file *file; char cwd_buf[CURRENTDIR_MAX]; if (this_fs->fs_ops->chdir) return this_fs->fs_ops->chdir(this_fs, src); /* Otherwise it is a "conventional filesystem" */ rv = searchdir(src); if (rv < 0) return rv; file = handle_to_file(rv); if (file->inode->mode != DT_DIR) { _close_file(file); return -1; } put_inode(this_fs->cwd); this_fs->cwd = get_inode(file->inode); _close_file(file); /* Save the current working directory */ realpath(cwd_buf, src, CURRENTDIR_MAX); /* Make sure the cwd_name ends in a slash, it's supposed to be a prefix */ join_paths(this_fs->cwd_name, CURRENTDIR_MAX, cwd_buf, "/"); return 0; }
__export int open_file(const char *name, int flags, struct com32_filedata *filedata) { int rv; struct file *file; char mangled_name[FILENAME_MAX]; dprintf("open_file %s\n", name); mangle_name(mangled_name, name); rv = searchdir(mangled_name, flags); if (rv < 0) return rv; file = handle_to_file(rv); if (file->inode->mode != DT_REG) { _close_file(file); return -1; } filedata->size = file->inode->size; filedata->blocklg2 = SECTOR_SHIFT(file->fs); filedata->handle = rv; return rv; }
void getfsbytes(com32sys_t *regs) { int sectors; bool have_more; uint32_t bytes_read; char *buf; struct file *file; uint16_t handle; handle = regs->esi.w[0]; file = handle_to_file(handle); sectors = regs->ecx.w[0] >> SECTOR_SHIFT(file->fs); buf = MK_PTR(regs->es, regs->ebx.w[0]); bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); /* * If we reach EOF, the filesystem driver will have already closed * the underlying file... this really should be cleaner. */ if (!have_more) { _close_file(file); regs->esi.w[0] = 0; } regs->ecx.l = bytes_read; }
int AudioStreamPlaybackOGGVorbis::mix(int16_t* p_bufer,int p_frames) { if (!playing) return 0; int total=p_frames; while (true) { int todo = p_frames; if (todo==0 || todo<MIN_MIX) { break; } //printf("to mix %i - mix me %i bytes\n",to_mix,to_mix*stream_channels*sizeof(int16_t)); #ifdef BIG_ENDIAN_ENABLED long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 1, 2, 1, ¤t_section); #else long ret=ov_read(&vf,(char*)p_bufer,todo*stream_channels*sizeof(int16_t), 0, 2, 1, ¤t_section); #endif if (ret<0) { playing = false; ERR_EXPLAIN("Error reading OGG Vorbis File: "+file); ERR_BREAK(ret<0); } else if (ret==0) { // end of song, reload? ov_clear(&vf); _close_file(); if (!has_loop()) { playing=false; repeats=1; break; } f=FileAccess::open(file,FileAccess::READ); int errv = ov_open_callbacks(f,&vf,NULL,0,_ov_callbacks); if (errv!=0) { playing=false; break;; // :( } if (loop_restart_time) { bool ok = ov_time_seek(&vf,loop_restart_time)==0; if (!ok) { playing=false; //ERR_EXPLAIN("loop restart time rejected"); ERR_PRINT("loop restart time rejected") } frames_mixed=stream_srate*loop_restart_time; } else {
__export void close_file(uint16_t handle) { struct file *file; if (handle) { file = handle_to_file(handle); _close_file(file); } }
void FileIODevice::send_data(const QByteArray &data) { lock_file(true); _open_file(true); // At this point the settings file is ours for sole writing QT_IODevice::send_data(data); _close_file(); unlock_file(); }
void AudioStreamPlaybackOpus::_clear_stream() { if(!stream_loaded) return; op_free(opus_file); _close_file(); stream_loaded=false; stream_channels=1; playing=false; }
QByteArray FileIODevice::receive_data() { lock_file(false); _open_file(false); QByteArray ret = QT_IODevice::receive_data(); _close_file(); unlock_file(); _last_update_time = QFileInfo(FileName()).lastModified(); return ret; }
/*============================================================================== * - _ebook_cb_page() * * - when user release 'ebook' cbi, call this */ static OS_STATUS _ebook_cb_page (GUI_CBI *pCBI_ebook, GUI_COOR *pCoor) { if (pCoor->x < gra_scr_w() / 2) { _show_page (PAGE_PREV); } else { if (pCoor->y >= ICON_SIZE || pCoor->x < (gra_scr_w () - ICON_SIZE)) { _show_page (PAGE_NEXT); } else { _close_file (); } } return OS_STATUS_OK; }
int AudioStreamPlaybackOpus::mix(int16_t* p_bufer,int p_frames) { if (!playing) return 0; int total=p_frames; while (true) { int todo = p_frames; if (todo==0 || todo<MIN_MIX) { break; } int ret=op_read(opus_file,(opus_int16*)p_bufer,todo*stream_channels,¤t_section); if (ret<0) { playing = false; ERR_EXPLAIN("Error reading Opus File: "+file); ERR_BREAK(ret<0); } else if (ret==0) { // end of song, reload? op_free(opus_file); _close_file(); f=FileAccess::open(file,FileAccess::READ); int errv = 0; opus_file = op_open_callbacks(f,&_op_callbacks,NULL,0,&errv); if (errv!=0) { playing=false; break; // :( } if (!has_loop()) { playing=false; repeats=1; break; } if (loop_restart_time) { bool ok = op_pcm_seek(opus_file, (loop_restart_time*osrate)+pre_skip)==0; if (!ok) { playing=false; ERR_PRINT("loop restart time rejected") } frames_mixed=(loop_restart_time*osrate)+pre_skip; } else {
/* * Open a directory */ __export DIR *opendir(const char *path) { int rv; struct file *file; rv = searchdir(path, O_RDONLY|O_DIRECTORY); if (rv < 0) return NULL; file = handle_to_file(rv); if (file->inode->mode != DT_DIR) { _close_file(file); return NULL; } return (DIR *)file; }
size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors) { bool have_more; size_t bytes_read; struct file *file; file = handle_to_file(*handle); bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more); /* * If we reach EOF, the filesystem driver will have already closed * the underlying file... this really should be cleaner. */ if (!have_more) { _close_file(file); *handle = 0; } return bytes_read; }
void pm_load_high(com32sys_t *regs) { struct fs_info *fs; uint32_t bytes; uint32_t zero_mask; bool have_more; uint32_t bytes_read; char *buf, *limit; struct file *file; uint32_t sector_mask; size_t pad; uint32_t retflags = 0; bytes = regs->eax.l; zero_mask = regs->edx.w[0]; buf = (char *)regs->edi.l; limit = (char *)(regs->ebp.l & ~zero_mask); file = handle_to_file(regs->esi.w[0]); fs = file->fs; sector_mask = SECTOR_SIZE(fs) - 1; while (bytes) { uint32_t sectors; uint32_t chunk; if (buf + SECTOR_SIZE(fs) > limit) { /* Can't fit even one more sector in... */ retflags = EFLAGS_OF; break; } chunk = bytes; if (regs->ebx.w[0]) { call16((void (*)(void))(size_t)regs->ebx.w[0], &zero_regs, NULL); chunk = min(chunk, MAX_CHUNK); } if (chunk > (((char *)limit - buf) & ~sector_mask)) chunk = ((char *)limit - buf) & ~sector_mask; sectors = (chunk + sector_mask) >> SECTOR_SHIFT(fs); bytes_read = fs->fs_ops->getfssec(file, buf, sectors, &have_more); if (bytes_read > chunk) bytes_read = chunk; buf += bytes_read; bytes -= bytes_read; if (!have_more) { /* * If we reach EOF, the filesystem driver will have already closed * the underlying file... this really should be cleaner. */ _close_file(file); regs->esi.w[0] = 0; retflags = EFLAGS_CF; break; } } pad = (size_t)buf & zero_mask; if (pad) memset(buf, 0, pad); regs->ebx.l = (size_t)buf; regs->edi.l = (size_t)buf + pad; set_flags(regs, retflags); }
int searchdir(const char *name, int flags) { static char root_name[] = "/"; struct file *file; char *path, *inode_name, *next_inode_name; struct inode *tmp, *inode = NULL; int symlink_count = MAX_SYMLINK_CNT; dprintf("searchdir: %s root: %p cwd: %p\n", name, this_fs->root, this_fs->cwd); if (!(file = alloc_file())) goto err_no_close; file->fs = this_fs; /* if we have ->searchdir method, call it */ if (file->fs->fs_ops->searchdir) { file->fs->fs_ops->searchdir(name, flags, file); if (file->inode) return file_to_handle(file); else goto err; } /* else, try the generic-path-lookup method */ /* Copy the path */ path = strdup(name); if (!path) { dprintf("searchdir: Couldn't copy path\n"); goto err_path; } /* Work with the current directory, by default */ inode = get_inode(this_fs->cwd); if (!inode) { dprintf("searchdir: Couldn't use current directory\n"); goto err_curdir; } for (inode_name = path; inode_name; inode_name = next_inode_name) { /* Root directory? */ if (inode_name[0] == '/') { next_inode_name = inode_name + 1; inode_name = root_name; } else { /* Find the next inode name */ next_inode_name = strchr(inode_name + 1, '/'); if (next_inode_name) { /* Terminate the current inode name and point to next */ *next_inode_name++ = '\0'; } } if (next_inode_name) { /* Advance beyond redundant slashes */ while (*next_inode_name == '/') next_inode_name++; /* Check if we're at the end */ if (*next_inode_name == '\0') next_inode_name = NULL; } dprintf("searchdir: inode_name: %s\n", inode_name); if (next_inode_name) dprintf("searchdir: Remaining: %s\n", next_inode_name); /* Root directory? */ if (inode_name[0] == '/') { /* Release any chain that's already been established */ put_inode(inode); inode = get_inode(this_fs->root); continue; } /* Current directory? */ if (!strncmp(inode_name, ".", sizeof ".")) continue; /* Parent directory? */ if (!strncmp(inode_name, "..", sizeof "..")) { /* If there is no parent, just ignore it */ if (!inode->parent) continue; /* Add a reference to the parent so we can release the child */ tmp = get_inode(inode->parent); /* Releasing the child will drop the parent back down to 1 */ put_inode(inode); inode = tmp; continue; } /* Anything else */ tmp = inode; inode = this_fs->fs_ops->iget(inode_name, inode); if (!inode) { /* Failure. Release the chain */ put_inode(tmp); break; } /* Sanity-check */ if (inode->parent && inode->parent != tmp) { dprintf("searchdir: iget returned a different parent\n"); put_inode(inode); inode = NULL; put_inode(tmp); break; } inode->parent = tmp; inode->name = strdup(inode_name); dprintf("searchdir: path component: %s\n", inode->name); /* Symlink handling */ if (inode->mode == DT_LNK) { char *new_path; int new_len, copied; /* target path + NUL */ new_len = inode->size + 1; if (next_inode_name) { /* target path + slash + remaining + NUL */ new_len += strlen(next_inode_name) + 1; } if (!this_fs->fs_ops->readlink || /* limit checks */ --symlink_count == 0 || new_len > MAX_SYMLINK_BUF) goto err_new_len; new_path = malloc(new_len); if (!new_path) goto err_new_path; copied = this_fs->fs_ops->readlink(inode, new_path); if (copied <= 0) goto err_copied; new_path[copied] = '\0'; dprintf("searchdir: Symlink: %s\n", new_path); if (next_inode_name) { new_path[copied] = '/'; strcpy(new_path + copied + 1, next_inode_name); dprintf("searchdir: New path: %s\n", new_path); } free(path); path = next_inode_name = new_path; /* Add a reference to the parent so we can release the child */ tmp = get_inode(inode->parent); /* Releasing the child will drop the parent back down to 1 */ put_inode(inode); inode = tmp; continue; err_copied: free(new_path); err_new_path: err_new_len: put_inode(inode); inode = NULL; break; } /* If there's more to process, this should be a directory */ if (next_inode_name && inode->mode != DT_DIR) { dprintf("searchdir: Expected a directory\n"); put_inode(inode); inode = NULL; break; } } err_curdir: free(path); err_path: if (!inode) { dprintf("searchdir: Not found\n"); goto err; } file->inode = inode; file->offset = 0; return file_to_handle(file); err: dprintf("serachdir: error seraching file %s\n", name); _close_file(file); err_no_close: return -1; }
int searchdir(const char *name) { struct inode *inode = NULL; struct inode *parent = NULL; struct file *file; char *pathbuf = NULL; char *part, *p, echar; int symlink_count = MAX_SYMLINK_CNT; dprintf("searchdir: %s root: %p cwd: %p\n", name, this_fs->root, this_fs->cwd); if (!(file = alloc_file())) goto err_no_close; file->fs = this_fs; /* if we have ->searchdir method, call it */ if (file->fs->fs_ops->searchdir) { file->fs->fs_ops->searchdir(name, file); if (file->inode) return file_to_handle(file); else goto err; } /* else, try the generic-path-lookup method */ parent = get_inode(this_fs->cwd); p = pathbuf = strdup(name); if (!pathbuf) goto err; do { got_link: if (*p == '/') { put_inode(parent); parent = get_inode(this_fs->root); } do { inode = get_inode(parent); while (*p == '/') p++; if (!*p) break; part = p; while ((echar = *p) && echar != '/') p++; *p++ = '\0'; if (part[0] == '.' && part[1] == '.' && part[2] == '\0') { if (inode->parent) { put_inode(parent); parent = get_inode(inode->parent); put_inode(inode); inode = NULL; if (!echar) { /* Terminal double dots */ inode = parent; parent = inode->parent ? get_inode(inode->parent) : NULL; } } } else if (part[0] != '.' || part[1] != '\0') { inode = this_fs->fs_ops->iget(part, parent); if (!inode) goto err; if (inode->mode == DT_LNK) { char *linkbuf, *q; int name_len = echar ? strlen(p) : 0; int total_len = inode->size + name_len + 2; int link_len; if (!this_fs->fs_ops->readlink || --symlink_count == 0 || /* limit check */ total_len > MAX_SYMLINK_BUF) goto err; linkbuf = malloc(total_len); if (!linkbuf) goto err; link_len = this_fs->fs_ops->readlink(inode, linkbuf); if (link_len <= 0) { free(linkbuf); goto err; } q = linkbuf + link_len; if (echar) { if (link_len > 0 && q[-1] != '/') *q++ = '/'; memcpy(q, p, name_len+1); } else { *q = '\0'; } free(pathbuf); p = pathbuf = linkbuf; put_inode(inode); inode = NULL; goto got_link; } inode->name = strdup(part); dprintf("path component: %s\n", inode->name); inode->parent = parent; parent = NULL; if (!echar) break; if (inode->mode != DT_DIR) goto err; parent = inode; inode = NULL; } } while (echar); } while (0); free(pathbuf); pathbuf = NULL; put_inode(parent); parent = NULL; if (!inode) goto err; file->inode = inode; file->offset = 0; return file_to_handle(file); err: put_inode(inode); put_inode(parent); if (pathbuf) free(pathbuf); _close_file(file); err_no_close: return -1; }
/* * Close a directory */ __export int closedir(DIR *dir) { struct file *dd_dir = (struct file *)dir; _close_file(dd_dir); return 0; }