1
0
forked from 0ad/0ad

- file bugfix: truncate when opening for writing (problem reported by philip)

- file: now return size at close() time for use with VFS
- zip: tested open speed, added [exec time]  notes

This was SVN commit r2075.
This commit is contained in:
janwas 2005-03-29 06:27:35 +00:00
parent d60fc60a69
commit e86001f45e
5 changed files with 33 additions and 4 deletions

View File

@ -530,7 +530,7 @@ int file_open(const char* p_fn, const uint flags, File* f)
int oflag = O_RDONLY;
if(flags & FILE_WRITE)
oflag = O_WRONLY | O_CREAT;
oflag = O_WRONLY|O_CREAT|O_TRUNC;
// read access requested
else
{
@ -597,13 +597,17 @@ int file_close(File* f)
if(f->mapping) // only free if necessary (unmap complains if not mapped)
file_unmap(f);
// return final file size (required by VFS after writing files).
// this is much easier than updating when writing, because we'd have
// to add accounting code to both (sync and async) paths.
f->size = lseek(f->fd, 0, SEEK_END);
// (check fd to avoid BoundsChecker warning about invalid close() param)
if(f->fd != -1)
{
close(f->fd);
f->fd = -1;
}
f->size = 0;
return 0;
}
@ -988,7 +992,6 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
data_size = MIN(data_size, (size_t)bytes_left);
}
bool temp = (data_buf == 0);
// sanity checks:

View File

@ -118,6 +118,9 @@ extern int file_enum(const char* dir, FileCB cb, uintptr_t user);
extern int file_stat(const char* path, struct stat*);
extern int file_open(const char* fn, uint flags, File* f);
// note: final file size is calculated and returned in f->size.
// see implementation for rationale.
extern int file_close(File* f);

View File

@ -895,6 +895,8 @@ struct VFile
off_t ofs;
TFile* tf;
union
{
File f;
@ -945,8 +947,18 @@ static void VFile_dtor(VFile* vf)
if(flags & VF_ZIP)
zip_close(&vf->zf);
else
{
file_close(&vf->f);
// update file state in VFS tree
// (must be done after close, since that calculates the size)
if(flags & FILE_WRITE)
{
vf->tf->mtime = time(0);
vf->tf->size = vf->f.size;
}
}
flags &= ~(VF_OPEN);
}
@ -1001,6 +1013,7 @@ static int VFile_reload(VFile* vf, const char* v_path, Handle)
// success
flags |= VF_OPEN;
vf->tf = file;
return 0;
}

View File

@ -601,6 +601,8 @@ static TNode tree_root;
static TDir* tree_root_dir = &tree_root.u.dir;
// rationale: can't do this in tree_clear - we'd leak at exit.
// calling from tree_add* is ugly as well, so require manual init.
void tree_init()
{
tree_root_dir->init();

View File

@ -164,7 +164,7 @@ static int z_find_ecdr(const u8* file, size_t size, const u8*& ecdr_)
if(*(u32*)ecdr == *(u32*)&ecdr_id)
goto found_ecdr;
// jump crosses init, blah blah
// goto scoping
{
// scan the last 66000 bytes of file for ecdr_id signature
// (the Zip archive comment field, up to 64k, may follow ECDR).
@ -232,6 +232,8 @@ enum z_extract_cdfh_ret
// finally, advance to next CDFH.
// return -1 on error (output params invalid), or 0 on success.
// called by z_enum_files, which passes the output to lookup.
//
// [30ms]
static int z_extract_cdfh(const u8* file, size_t size, // in
const u8*& cdfh, const char*& fn, size_t& fn_len, ZLoc* loc) // out
{
@ -308,6 +310,7 @@ static int z_extract_cdfh(const u8* file, size_t size, // in
// loc is only valid during the callback! must be copied or saved.
typedef int(*CDFH_CB)(uintptr_t user, i32 idx, const char* fn, size_t fn_len, const ZLoc* loc);
static int z_enum_files(const u8* file, const size_t size, const CDFH_CB cb, const uintptr_t user)
{
// find "End of Central Directory Record"
@ -332,11 +335,13 @@ static int z_enum_files(const u8* file, const size_t size, const CDFH_CB cb, con
// only incremented when valid, so we don't leave holes
// in lookup's arrays (bad locality).
for(i32 i = 0; i < num_entries; i++)
{
const char* fn;
size_t fn_len;
ZLoc loc;
int ret = z_extract_cdfh(file, size, cdfh, fn, fn_len, &loc);
// valid file
if(ret == Z_CDFH_FILE_OK)
@ -425,6 +430,8 @@ struct LookupInfo
// notes:
// - fn (filename) is not necessarily 0-terminated!
// - loc is only valid during the callback! must be copied or saved.
//
// [40ms]
static int lookup_add_file_cb(uintptr_t user, i32 idx,
const char* fn, size_t fn_len, const ZLoc* loc)
{
@ -673,6 +680,7 @@ fail_close:
// somewhat slow - each file is added to an internal index.
Handle zip_archive_open(const char* fn)
{
TIMER(zip_archive_open);
return h_alloc(H_ZArchive, fn);
}