forked from 0ad/0ad
# VFS: add support for redirecting writes of files that are in archives to writable mod directory (required for editor)
This was SVN commit r3818.
This commit is contained in:
parent
11e53a3ce0
commit
2bd3708339
@ -438,8 +438,9 @@ ERR(-100330, ERR_IO, "Error during IO")
|
||||
ERR(-100331, ERR_EOF, "Reading beyond end of file")
|
||||
// .. mount
|
||||
ERR(-100340, ERR_ALREADY_MOUNTED, "Directory (tree) already mounted")
|
||||
ERR(-100341, ERR_INVALID_MOUNT_TYPE, "Invalid mount type (memory corruption?)")
|
||||
ERR(-100342, ERR_ROOT_DIR_ALREADY_SET, "Attempting to set FS root dir more than once")
|
||||
ERR(-100341, ERR_NOT_MOUNTED, "Specified directory is not mounted")
|
||||
ERR(-100342, ERR_INVALID_MOUNT_TYPE, "Invalid mount type (memory corruption?)")
|
||||
ERR(-100343, ERR_ROOT_DIR_ALREADY_SET, "Attempting to set FS root dir more than once")
|
||||
// .. misc
|
||||
ERR(-100350, ERR_UNKNOWN_CMETHOD, "Unknown/unsupported compression method")
|
||||
ERR(-100351, ERR_IS_COMPRESSED, "Invalid operation for a compressed file")
|
||||
|
@ -269,9 +269,13 @@ enum FileFlags
|
||||
// promising they will set atom_fn).
|
||||
FILE_DONT_SET_FN = 0x80,
|
||||
|
||||
// sum of all flags above. used when validating flag parameters and
|
||||
// by zip.cpp because its flags live alongside these.
|
||||
FILE_FLAG_ALL = 0xFF
|
||||
// (only relevant for VFS) file will be written into the
|
||||
// appropriate subdirectory of the mount point established by
|
||||
// vfs_mod_set_write_target. see documentation there.
|
||||
FILE_WRITE_TO_MOD = FILE_WRITE|0x100,
|
||||
|
||||
// sum of all flags above. used when validating flag parameters.
|
||||
FILE_FLAG_ALL = 0x1FF
|
||||
};
|
||||
|
||||
|
||||
|
@ -360,9 +360,7 @@ LibError vfs_stat(const char* V_path, struct stat* s)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct VFile
|
||||
{
|
||||
@ -423,6 +421,9 @@ static LibError VFile_reload(VFile* vf, const char* V_path, Handle)
|
||||
return err;
|
||||
}
|
||||
|
||||
if(flags & FILE_WRITE_TO_MOD)
|
||||
RETURN_ERR(set_mount_to_mod_target(tf));
|
||||
|
||||
RETURN_ERR(xfile_open(V_path, flags, tf, &vf->f));
|
||||
|
||||
stats_open(vf->f.atom_fn, vf->f.size);
|
||||
|
@ -288,6 +288,15 @@ extern LibError vfs_mount(const char* V_mount_point, const char* P_real_dir, uin
|
||||
// unmount a previously mounted item, and rebuild the VFS afterwards.
|
||||
extern LibError vfs_unmount(const char* name);
|
||||
|
||||
// set current "mod write directory" to P_target_dir, which must
|
||||
// already have been mounted into the VFS.
|
||||
// all files opened for writing with the FILE_WRITE_TO_MOD flag set will
|
||||
// be written into the appropriate subdirectory of this mount point.
|
||||
//
|
||||
// this allows e.g. the editor to write files that are already
|
||||
// stored in archives, which are read-only.
|
||||
extern LibError vfs_mod_set_write_target(const char* P_target_dir);
|
||||
|
||||
|
||||
//
|
||||
// directory entry
|
||||
|
@ -676,7 +676,7 @@ struct IsArchiveMount
|
||||
{
|
||||
bool operator()(const Mount& m) const
|
||||
{
|
||||
return (m.archive > 0);
|
||||
return (m.type == MT_ARCHIVE);
|
||||
}
|
||||
};
|
||||
|
||||
@ -740,6 +740,60 @@ LibError mount_make_vfs_path(const char* P_path, char* V_path)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const Mount* mod_target;
|
||||
|
||||
// set current "mod write directory" to P_target_dir, which must
|
||||
// already have been mounted into the VFS.
|
||||
// all files opened for writing with the FILE_WRITE_TO_MOD flag set will
|
||||
// be written into the appropriate subdirectory of this mount point.
|
||||
//
|
||||
// this allows e.g. the editor to write files that are already
|
||||
// stored in archives, which are read-only.
|
||||
LibError vfs_mod_set_write_target(const char* P_target_dir)
|
||||
{
|
||||
for(MountIt it = mounts.begin(); it != mounts.end(); ++it)
|
||||
{
|
||||
const Mount& m = *it;
|
||||
// skip if not a directory mounting
|
||||
if(m.type != MT_FILE)
|
||||
continue;
|
||||
|
||||
// found it in list of mounted dirs
|
||||
if(!strcmp(m.P_name.c_str(), P_target_dir))
|
||||
{
|
||||
mod_target = &m;
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
WARN_RETURN(ERR_NOT_MOUNTED);
|
||||
}
|
||||
|
||||
|
||||
// 'relocate' tf to the mounting established by vfs_mod_set_write_target.
|
||||
// call if <tf> is being opened with FILE_WRITE_TO_MOD flag set.
|
||||
LibError set_mount_to_mod_target(TFile* tf)
|
||||
{
|
||||
if(!mod_target)
|
||||
WARN_RETURN(ERR_NOT_MOUNTED);
|
||||
|
||||
tfile_set_mount(tf, mod_target);
|
||||
|
||||
// invalidate the previous values. we don't need to be clever and
|
||||
// set size to that of the file in the new mod_target mount point.
|
||||
// this is because we're only called for files that are being
|
||||
// opened for writing, which will change these values anyway.
|
||||
tree_update_file(tf, 0, 0);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void mount_init()
|
||||
{
|
||||
tree_init();
|
||||
|
@ -95,6 +95,10 @@ extern LibError mount_populate(TDir* td, RealDir* rd);
|
||||
// because this call leaves the VFS in limbo!!
|
||||
extern void mount_release_all_archives();
|
||||
|
||||
// 'relocate' tf to the mounting established by vfs_mod_set_write_target.
|
||||
// call if <tf> is being opened with FILE_WRITE_TO_MOD flag set.
|
||||
extern LibError set_mount_to_mod_target(TFile* tf);
|
||||
|
||||
|
||||
// rebuild the VFS, i.e. re-mount everything. open files are not affected.
|
||||
// necessary after loose files or directories change, so that the VFS
|
||||
|
@ -702,6 +702,11 @@ const char* tfile_get_atom_fn(const TFile* tf)
|
||||
|
||||
|
||||
|
||||
void tfile_set_mount(TFile* tf, const Mount* m)
|
||||
{
|
||||
tf->m = m;
|
||||
}
|
||||
|
||||
void tree_update_file(TFile* tf, off_t size, time_t mtime)
|
||||
{
|
||||
tf->size = size;
|
||||
|
@ -113,6 +113,7 @@ extern const Mount* tfile_get_mount(const TFile* tf);
|
||||
extern uintptr_t tfile_get_memento(const TFile* tf);
|
||||
extern const char* tfile_get_atom_fn(const TFile* tf);
|
||||
|
||||
extern void tfile_set_mount(TFile* tf, const Mount* m);
|
||||
extern void tree_update_file(TFile* tf, off_t size, time_t mtime);
|
||||
|
||||
struct RealDir;
|
||||
|
Loading…
Reference in New Issue
Block a user