# HG changeset patch # User Paul Boddie # Date 1641336236 -3600 # Node ID 9cfd2fb90c331d63c10e799500c6620fdba8e327 # Parent ded81f25f1aae24d7f01f88f83b2d0e10a8ea1f4 Added initial support for file removal. diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsclient/include/fsclient/client.h --- a/libfsclient/include/fsclient/client.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsclient/include/fsclient/client.h Tue Jan 04 23:43:56 2022 +0100 @@ -47,6 +47,11 @@ long client_pipe(file_t **reader, file_t **writer, flags_t flags); long client_pipe_using(file_t **reader, file_t **writer, flags_t flags, l4_cap_idx_t server); +/* Other file operations. */ + +long client_remove(const char *name); +long client_remove_using(const char *name, l4_cap_idx_t server); + /* File and region operations. */ long client_flush(file_t *file); diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsclient/include/fsclient/file.h --- a/libfsclient/include/fsclient/file.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsclient/include/fsclient/file.h Tue Jan 04 23:43:56 2022 +0100 @@ -84,11 +84,13 @@ void file_close(file_t *file); long file_open(file_t *file, const char *filename, flags_t flags, l4_cap_idx_t server); +long file_remove(const char *filename, l4_cap_idx_t server); /* File lifecycle operations. */ long file_context(file_t *file, l4_cap_idx_t server); long file_context_open(file_t *file, flags_t flags, file_t *context); +long file_context_remove(file_t *context); void file_init(file_t *file); /* File and region operations. */ diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsclient/lib/src/client.cc Tue Jan 04 23:43:56 2022 +0100 @@ -359,6 +359,24 @@ +/* Remove a file from the filesystem. */ + +long client_remove(const char *name) +{ + l4_cap_idx_t server = l4re_env_get_cap("server"); + + return client_remove_using(name, server); +} + +/* Remove a file from the filesystem via a named capability. */ + +long client_remove_using(const char *name, l4_cap_idx_t server) +{ + return file_remove(name, server); +} + + + /* Obtain the current region of a pipe. */ long client_current_region(file_t *file) diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsclient/lib/src/file.cc Tue Jan 04 23:43:56 2022 +0100 @@ -137,6 +137,30 @@ return err; } +/* Remove a file from the filesystem. This is a convenience function invoking + file_context and file_context_remove. */ + +long file_remove(const char *filename, l4_cap_idx_t server) +{ + file_t context; + long err; + + err = file_context(&context, server); + if (err) + return err; + + if (!file_string_set(&context, filename, 0, NULL)) + return -L4_ENOMEM; + + err = file_context_remove(&context); + + /* Close the context, although a separate mechanism could permit contexts to + open several files. */ + + file_close(&context); + return err; +} + /* Initialise a file structure for a context obtained from the given server @@ -179,6 +203,14 @@ return openercontext.open(flags, &file->size, &file->ref, &file->object_flags); } +/* Remove a file using the given context. */ + +long file_context_remove(file_t *context) +{ + client_OpenerContext openercontext(context->ref); + return openercontext.remove(); +} + /* Flush populated data and obtain an updated file size and populated data diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/accessor.h --- a/libfsserver/include/fsserver/accessor.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/accessor.h Tue Jan 04 23:43:56 2022 +0100 @@ -57,6 +57,10 @@ virtual void fill(Flexpage *flexpage); virtual void flush(Flexpage *flexpage); + + /* Lifecycle methods. */ + + virtual void remove(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/ext2_file_accessor.h --- a/libfsserver/include/fsserver/ext2_file_accessor.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/ext2_file_accessor.h Tue Jan 04 23:43:56 2022 +0100 @@ -51,6 +51,8 @@ virtual offset_t get_size(); virtual void set_size(offset_t size); + + virtual void remove(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/ext2_file_opener.h --- a/libfsserver/include/fsserver/ext2_file_opener.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/ext2_file_opener.h Tue Jan 04 23:43:56 2022 +0100 @@ -62,6 +62,10 @@ virtual long make_directory_accessor(const char *path, flags_t flags, fileid_t fileid, DirectoryAccessor **accessor); + + virtual long remove_object(const char *path, fileid_t fileid); + + virtual long unlink_object(const char *path, fileid_t fileid); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/ext2_file_operations.h --- a/libfsserver/include/fsserver/ext2_file_operations.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/ext2_file_operations.h Tue Jan 04 23:43:56 2022 +0100 @@ -61,23 +61,33 @@ bool is_file(ext2_ino_t ino_file); + void close_file(ext2_file_t file); + long create_file(ext2_ino_t ino_parent, const char *filename, user_t user, ext2_ino_t *ino); long find_file(const char *path, ext2_ino_t *ino, const char **remaining); - void close_file(ext2_file_t file); + long open_file(ext2_ino_t ino, ext2_file_t *file); + + long remove(ext2_ino_t ino); - long open_file(ext2_ino_t ino, ext2_file_t *file); + long unlink(ext2_ino_t ino_parent, ext2_ino_t ino); + + /* File property methods. */ offset_t get_size(ext2_file_t file); void set_size(ext2_file_t file, offset_t size); + /* File access methods. */ + offset_t read_file(ext2_file_t file, offset_t filepos, void *addr, offset_t size); void write_file(ext2_file_t file, offset_t filepos, const void *addr, offset_t size); + /* Directory access. */ + long directory_iterate(ext2_ino_t dir, int func(struct ext2_dir_entry *, int, int, char *, void *), void *priv_data); diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/file_opening.h --- a/libfsserver/include/fsserver/file_opening.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/file_opening.h Tue Jan 04 23:43:56 2022 +0100 @@ -43,6 +43,10 @@ virtual long make_directory_accessor(const char *path, flags_t flags, fileid_t fileid, DirectoryAccessor **accessor) = 0; + + virtual long remove_object(const char *path, fileid_t fileid) = 0; + + virtual long unlink_object(const char *path, fileid_t fileid) = 0; }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/file_provider.h --- a/libfsserver/include/fsserver/file_provider.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/file_provider.h Tue Jan 04 23:43:56 2022 +0100 @@ -44,6 +44,8 @@ virtual long make_resource(offset_t *size, object_flags_t *object_flags, Resource **resource); + + virtual void remove(); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/host_file_opener.h --- a/libfsserver/include/fsserver/host_file_opener.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/host_file_opener.h Tue Jan 04 23:43:56 2022 +0100 @@ -72,6 +72,10 @@ virtual long make_directory_accessor(const char *path, flags_t flags, fileid_t fileid, DirectoryAccessor **accessor); + + virtual long remove_object(const char *path, fileid_t fileid); + + virtual long unlink_object(const char *path, fileid_t fileid); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/opener_context_resource.h --- a/libfsserver/include/fsserver/opener_context_resource.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/opener_context_resource.h Tue Jan 04 23:43:56 2022 +0100 @@ -60,6 +60,8 @@ long open(flags_t flags, offset_t *size, l4_cap_idx_t *file, object_flags_t *object_flags); + long remove(); + /* Pager/dataspace methods. */ long map(unsigned long offset, address_t hot_spot, map_flags_t flags, diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/opener_resource.h --- a/libfsserver/include/fsserver/opener_resource.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/opener_resource.h Tue Jan 04 23:43:56 2022 +0100 @@ -63,6 +63,8 @@ long open(const char *path, flags_t flags, offset_t *size, l4_cap_idx_t *cap, object_flags_t *object_flags); + long remove(const char *path); + /* Opener interface methods. */ long context(l4_cap_idx_t *context); diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/provider.h --- a/libfsserver/include/fsserver/provider.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/provider.h Tue Jan 04 23:43:56 2022 +0100 @@ -35,6 +35,7 @@ protected: fileid_t _fileid; ProviderRegistry *_registry; + bool _remove = false; public: explicit Provider(fileid_t fileid, ProviderRegistry *registry); @@ -45,6 +46,14 @@ virtual long make_resource(offset_t *size, object_flags_t *object_flags, Resource **resource) = 0; + + /* Lifecycle methods. */ + + virtual bool removal_pending(); + + virtual void remove(); + + virtual void remove_pending(bool remove); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/provider_registry.h --- a/libfsserver/include/fsserver/provider_registry.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/provider_registry.h Tue Jan 04 23:43:56 2022 +0100 @@ -49,6 +49,7 @@ ProviderMapping _providers; std::mutex _lock; +public: /* Filesystem object access. */ Provider *get(fileid_t fileid); @@ -57,7 +58,6 @@ void set(fileid_t fileid, Provider *obj); -public: /* Methods for resources. */ void detach(fileid_t fileid, Provider *mapper); diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/resource_registry.h --- a/libfsserver/include/fsserver/resource_registry.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/resource_registry.h Tue Jan 04 23:43:56 2022 +0100 @@ -56,7 +56,8 @@ public: explicit ResourceRegistry(Pages *pages); - /* Resource discovery methods. */ + /* Provider discovery methods. + NOTE: To be protected, potentially. */ long find_provider(fileid_t fileid, Provider **provider); @@ -65,6 +66,10 @@ long get_resource(FileOpening *opening, const char *path, flags_t flags, offset_t *size, object_flags_t *object_flags, Resource **resource); + + /* Provider manipulation methods. */ + + long remove_provider(FileOpening *opening, const char *path); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/include/fsserver/test_file_opener.h --- a/libfsserver/include/fsserver/test_file_opener.h Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/include/fsserver/test_file_opener.h Tue Jan 04 23:43:56 2022 +0100 @@ -53,6 +53,10 @@ virtual long make_directory_accessor(const char *path, flags_t flags, fileid_t fileid, DirectoryAccessor **accessor); + + virtual long remove_object(const char *path, fileid_t fileid); + + virtual long unlink_object(const char *path, fileid_t fileid); }; // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/ext2_file_accessor.cc --- a/libfsserver/lib/files/ext2_file_accessor.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/ext2_file_accessor.cc Tue Jan 04 23:43:56 2022 +0100 @@ -100,4 +100,15 @@ _ops->write_file(_file, filepos, (const void *) addr, populated_size); } + + +/* Lifecycle methods. */ + +/* Remove the underlying filesystem object. */ + +void Ext2FileAccessor::remove() +{ + _ops->remove(fileid); +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/ext2_file_opener.cc --- a/libfsserver/lib/files/ext2_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/ext2_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 @@ -120,4 +120,26 @@ return L4_EOK; } +/* Remove a filesystem object. */ + +long Ext2FileOpener::remove_object(const char *path, fileid_t fileid) +{ + (void) path; + + return _ops->remove((ext2_ino_t) fileid); +} + +/* Unlink a filesystem object. */ + +long Ext2FileOpener::unlink_object(const char *path, fileid_t fileid) +{ + fileid_t parent; + long err = get_parent(path, &parent); + + if (err) + return err; + + return _ops->unlink((ext2_ino_t) parent, (ext2_ino_t) fileid); +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/ext2_file_operations.cc --- a/libfsserver/lib/files/ext2_file_operations.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/ext2_file_operations.cc Tue Jan 04 23:43:56 2022 +0100 @@ -113,6 +113,38 @@ return L4_EOK; } +/* Remove an object from a directory. */ + +long Ext2FileOperations::remove(ext2_ino_t ino) +{ + std::lock_guard guard(_lock); + + errcode_t retval = image_remove_by_inode(_fs, ino); + + // NOTE: Map error conditions. + + if (retval) + return -L4_EIO; + + return L4_EOK; +} + +/* Unlink an object from a directory. */ + +long Ext2FileOperations::unlink(ext2_ino_t ino_parent, ext2_ino_t ino) +{ + std::lock_guard guard(_lock); + + errcode_t retval = image_unlink_by_inode(_fs, ino_parent, ino); + + // NOTE: Map error conditions. + + if (retval) + return -L4_EIO; + + return L4_EOK; +} + /* Obtain the size of a file. */ offset_t Ext2FileOperations::get_size(ext2_file_t file) diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/file_provider.cc --- a/libfsserver/lib/files/file_provider.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/file_provider.cc Tue Jan 04 23:43:56 2022 +0100 @@ -73,4 +73,13 @@ return L4_EOK; } +/* Lifecycle methods. */ + +/* Remove the file using the accessor. */ + +void FileProvider::remove() +{ + _mapper->accessor()->remove(); +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/host_file_opener.cc --- a/libfsserver/lib/files/host_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/host_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 @@ -20,6 +20,7 @@ */ #include +#include #include @@ -131,4 +132,39 @@ return L4_EOK; } +/* Remove a filesystem object. */ + +long HostFileOpener::remove_object(const char *path, fileid_t fileid) +{ + (void) path; (void) fileid; + return L4_EOK; +} + +/* Unlink a filesystem object. */ + +long HostFileOpener::unlink_object(const char *path, fileid_t fileid) +{ + /* Ignore the fileid and always use the path. */ + + (void) fileid; + + // NOTE: Return code may need converting. + + int err = unlink(path); + + if (err) + return err; + + /* Remove the file identifier mapping. */ + + std::string s(path); + + HostFileIdentifiers::iterator it = _fileids.find(s); + + if (it != _fileids.end()) + _fileids.erase(it); + + return L4_EOK; +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/opener_context_resource.cc --- a/libfsserver/lib/files/opener_context_resource.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/opener_context_resource.cc Tue Jan 04 23:43:56 2022 +0100 @@ -78,4 +78,14 @@ return _opener->open(path, flags, size, file, object_flags); } +long OpenerContextResource::remove() +{ + char *path = get_path(); + + if (path == NULL) + return -L4_EINVAL; + + return _opener->remove(path); +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/opener_resource.cc --- a/libfsserver/lib/files/opener_resource.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/opener_resource.cc Tue Jan 04 23:43:56 2022 +0100 @@ -74,7 +74,8 @@ } /* Obtain any active parent directory for a path, notifying its subscribers of - the file opening event. */ + the file opening event. + NOTE: This might need to happen in the registry due to concurrency issues. */ long OpenerResource::notify_parent(const char *path) { @@ -124,6 +125,13 @@ return ResourceServer(resource).start_thread(cap); } +/* Request the removal of the named filesystem object. */ + +long OpenerResource::remove(const char *path) +{ + return _registry->remove_provider(this, path); +} + /* Opener interface methods. */ diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/files/test_file_opener.cc --- a/libfsserver/lib/files/test_file_opener.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/files/test_file_opener.cc Tue Jan 04 23:43:56 2022 +0100 @@ -79,4 +79,20 @@ return -L4_EIO; } +/* Remove a filesystem object. */ + +long TestFileOpener::remove_object(const char *path, fileid_t fileid) +{ + (void) path; (void) fileid; + return L4_EOK; +} + +/* Unlink a filesystem object. */ + +long TestFileOpener::unlink_object(const char *path, fileid_t fileid) +{ + (void) path; (void) fileid; + return -L4_EIO; +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/generic/accessor.cc --- a/libfsserver/lib/generic/accessor.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/generic/accessor.cc Tue Jan 04 23:43:56 2022 +0100 @@ -76,4 +76,12 @@ (void) flexpage; } +/* Lifecycle methods. */ + +/* Remove a filesystem object. */ + +void Accessor::remove() +{ +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/generic/provider.cc --- a/libfsserver/lib/generic/provider.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/generic/provider.cc Tue Jan 04 23:43:56 2022 +0100 @@ -37,4 +37,18 @@ return _registry; } +bool Provider::removal_pending() +{ + return _remove; +} + +void Provider::remove() +{ +} + +void Provider::remove_pending(bool remove) +{ + _remove = remove; +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/generic/provider_registry.cc --- a/libfsserver/lib/generic/provider_registry.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/generic/provider_registry.cc Tue Jan 04 23:43:56 2022 +0100 @@ -74,7 +74,16 @@ std::lock_guard guard(_lock); if (!provider->detach()) + { + /* Remove any underlying object if pending. */ + + if (provider->removal_pending()) + provider->remove(); + + /* Remove from the registry. */ + remove(fileid, provider); + } } // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libfsserver/lib/generic/resource_registry.cc --- a/libfsserver/lib/generic/resource_registry.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/libfsserver/lib/generic/resource_registry.cc Tue Jan 04 23:43:56 2022 +0100 @@ -169,4 +169,44 @@ return provider->make_resource(size, object_flags, resource); } +/* Request the removal of a filesystem object through any active provider. */ + +long ResourceRegistry::remove_provider(FileOpening *opening, const char *path) +{ + std::lock_guard guard(_lock); + + /* Obtain an identifier for any recognised object. */ + + fileid_t fileid; + long err = opening->get_fileid(path, 0, &fileid); + + if (err) + return err; + + /* Obtain a provider for the object. */ + + Provider *provider; + err = find_provider(fileid, &provider); + + if (err && (err != -L4_ENOENT)) + return err; + + /* Unlink the object regardless of whether it can be removed. */ + + err = opening->unlink_object(path, fileid); + + if (err) + return err; + + /* Without a provider being active, remove the object directly. */ + + if (err) + return opening->remove_object(path, fileid); + + /* With a provider active, request the object's removal upon closure. */ + + provider->remove_pending(true); + return L4_EOK; +} + // vim: tabstop=4 expandtab shiftwidth=4 diff -r ded81f25f1aa -r 9cfd2fb90c33 libsystypes/idl/opener_context.idl --- a/libsystypes/idl/opener_context.idl Tue Jan 04 23:27:53 2022 +0100 +++ b/libsystypes/idl/opener_context.idl Tue Jan 04 23:43:56 2022 +0100 @@ -1,7 +1,8 @@ #include /* flags_t, object_flags_t, offset_t */ -/* An interface providing a way of opening filesystem objects relying on a - dataspace to transfer filesystem paths. */ +/* An interface providing a way of opening or manipulating filesystem objects + relying on a dataspace to transfer filesystem paths specifying the objects + involved. */ interface OpenerContext { @@ -18,6 +19,10 @@ [opcode(12)] void open(in flags_t flags, out offset_t size, out cap file, out object_flags_t object_flags); + + /* Remove a file using a path written to the context's dataspace. */ + + [opcode(14)] void remove(); }; /* vim: tabstop=2 expandtab shiftwidth=2 diff -r ded81f25f1aa -r 9cfd2fb90c33 tests/dstest_file_readdir_concurrent.cc --- a/tests/dstest_file_readdir_concurrent.cc Tue Jan 04 23:27:53 2022 +0100 +++ b/tests/dstest_file_readdir_concurrent.cc Tue Jan 04 23:43:56 2022 +0100 @@ -79,6 +79,30 @@ } } +static long remove_file(char *filename, bool have_uid, sys_uid_t uid) +{ + /* With a user, open a user-specific file opener. */ + + if (have_uid) + { + l4_cap_idx_t opener = client_open_for_user((user_t) {uid, uid, 0022}); + + if (l4_is_invalid_cap(opener)) + { + printf("Could not obtain opener for file.\n"); + return -L4_EIO; + } + + /* Invoke the remove method to remove the file. */ + + return client_remove_using(filename, opener); + } + else + { + return client_remove(filename); + } +} + int main(int argc, char *argv[]) @@ -108,7 +132,9 @@ struct dirent *dirent; int filenum = 1000, remaining = 100; char buffer[strlen(filename) + strlen("/file-XXXX.txt") + 10]; + char data[256]; int found = 0; + file_t *files[100]; while ((dirent = client_readdir(reader)) != NULL) { @@ -129,6 +155,15 @@ return 1; } + /* Write something to each file. */ + + sprintf(data, "Data in file-%d.txt", filenum - 1); + client_write(file, data, strlen(data)); + + /* Remember the file for later. */ + + files[remaining - 1] = file; + remaining--; } } @@ -155,6 +190,54 @@ printf("Files found: %d\n", found); + /* Remove some files. */ + + for (filenum = 1000, remaining = 100; remaining > 0; remaining--) + { + sprintf(buffer, "%s/file-%d.txt", filename, filenum++); + + long err = remove_file(buffer, have_uid, uid); + + if (err) + { + printf("Could not remove file: %s\n", buffer); + return 1; + } + } + + /* Re-read, counting files. */ + + reader = open_directory(filename, have_uid, uid); + + if (reader == NULL) + { + printf("Could not read from directory.\n"); + return 1; + } + + found = 0; + + while ((dirent = client_readdir(reader)) != NULL) + { + free(dirent); + found++; + } + + printf("Files found: %d\n", found); + + /* Read from the still-open but now removed files. */ + + for (remaining = 0; remaining < 100; remaining++) + { + file_t *file = files[remaining]; + + client_seek(file, SEEK_SET, 0); + offset_t nread = client_read(file, data, 256); + + data[nread] = '\0'; + printf("Read: %s\n", data); + } + return 0; }