From 5d434944eb42524d9fda05a0aeae8964e5ee2c7b Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 18 Sep 2015 11:10:29 +0200 Subject: [PATCH] libc: support access() in plugins Fixes #1703 --- repos/libports/include/libc-plugin/plugin.h | 2 ++ .../libports/include/libc-plugin/plugin_registry.h | 3 ++- repos/libports/src/lib/libc/dummies.cc | 1 - repos/libports/src/lib/libc/file_operations.cc | 13 +++++++++++++ repos/libports/src/lib/libc/plugin.cc | 7 +++++++ repos/libports/src/lib/libc/plugin_registry.cc | 3 +++ repos/libports/src/lib/libc/vfs_plugin.cc | 6 ++++++ 7 files changed, 33 insertions(+), 2 deletions(-) diff --git a/repos/libports/include/libc-plugin/plugin.h b/repos/libports/include/libc-plugin/plugin.h index 1005685907..4ab781370e 100644 --- a/repos/libports/include/libc-plugin/plugin.h +++ b/repos/libports/include/libc-plugin/plugin.h @@ -44,6 +44,7 @@ namespace Libc { virtual int priority(); + virtual bool supports_access(char const *path, int amode); virtual bool supports_execve(char const *filename, char *const argv[], char *const envp[]); virtual bool supports_mkdir(const char *path, mode_t mode); @@ -70,6 +71,7 @@ namespace Libc { virtual File_descriptor *accept(File_descriptor *, struct ::sockaddr *addr, socklen_t *addrlen); + virtual int access(char const *, int); virtual int bind(File_descriptor *, const struct ::sockaddr *addr, socklen_t addrlen); diff --git a/repos/libports/include/libc-plugin/plugin_registry.h b/repos/libports/include/libc-plugin/plugin_registry.h index 909463f6c6..841ba1b36e 100644 --- a/repos/libports/include/libc-plugin/plugin_registry.h +++ b/repos/libports/include/libc-plugin/plugin_registry.h @@ -24,7 +24,8 @@ namespace Libc { class Plugin_registry : public List { public: - + + Plugin *get_plugin_for_access(char const *pathname, int amode); Plugin *get_plugin_for_execve(char const *filename, char *const argv[], char *const envp[]); Plugin *get_plugin_for_freeaddrinfo(struct addrinfo *res); diff --git a/repos/libports/src/lib/libc/dummies.cc b/repos/libports/src/lib/libc/dummies.cc index 954aafd745..9460ea85d3 100644 --- a/repos/libports/src/lib/libc/dummies.cc +++ b/repos/libports/src/lib/libc/dummies.cc @@ -43,7 +43,6 @@ ret_type name args \ return ret_val; \ } -DUMMY(int , -1, access, (const char *, int)) DUMMY(int , -1, chmod, (const char *, mode_t)) DUMMY(int , -1, chown, (const char *, uid_t, gid_t)) DUMMY(int , -1, chroot, (const char *)) diff --git a/repos/libports/src/lib/libc/file_operations.cc b/repos/libports/src/lib/libc/file_operations.cc index 8b36671f81..1ade7983c3 100644 --- a/repos/libports/src/lib/libc/file_operations.cc +++ b/repos/libports/src/lib/libc/file_operations.cc @@ -214,6 +214,19 @@ static void resolve_symlinks_except_last_element(char const *path, Absolute_path ** Libc functions ** ********************/ +extern "C" int access(const char *path, int amode) +{ + try { + Absolute_path resolved_path; + resolve_symlinks(path, resolved_path); + FNAME_FUNC_WRAPPER(access, resolved_path.base(), amode); + } catch (Symlink_resolve_error) { + errno = ENOENT; + return -1; + } +} + + extern "C" int chdir(const char *path) { struct stat stat_buf; diff --git a/repos/libports/src/lib/libc/plugin.cc b/repos/libports/src/lib/libc/plugin.cc index 3d8ce93681..6df33b78f8 100644 --- a/repos/libports/src/lib/libc/plugin.cc +++ b/repos/libports/src/lib/libc/plugin.cc @@ -42,6 +42,12 @@ int Plugin::priority() } +bool Plugin::supports_access(char const *path, int amode) +{ + return false; +} + + bool Plugin::supports_execve(char const *filename, char *const argv[], char *const envp[]) { @@ -189,6 +195,7 @@ DUMMY(ssize_t, -1, write, (File_descriptor *, const void *, ::size_t)); /* * Misc */ +DUMMY(int, -1, access, (char const *, int)); DUMMY(int, -1, execve, (char const *, char *const[], char *const[])); DUMMY(void, , freeaddrinfo, (struct ::addrinfo *)); DUMMY(int, -1, getaddrinfo, (const char *, const char *, const struct ::addrinfo *, struct ::addrinfo **)); diff --git a/repos/libports/src/lib/libc/plugin_registry.cc b/repos/libports/src/lib/libc/plugin_registry.cc index 295d1ca2d2..0d38498481 100644 --- a/repos/libports/src/lib/libc/plugin_registry.cc +++ b/repos/libports/src/lib/libc/plugin_registry.cc @@ -37,6 +37,9 @@ using namespace Libc; } \ return result; +Plugin *Plugin_registry::get_plugin_for_access(char const *path, int amode) { + GET_PLUGIN_FOR(access, path, amode) } + Plugin *Plugin_registry::get_plugin_for_execve(char const *filename, char *const argv[], char *const envp[]) { GET_PLUGIN_FOR(execve, filename, argv, envp) } diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index 56cc4309f7..a1f0f184b0 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -210,6 +210,7 @@ class Libc::Vfs_plugin : public Libc::Plugin ~Vfs_plugin() { } + bool supports_access(const char *, int) override { return true; } bool supports_mkdir(const char *, mode_t) override { return true; } bool supports_open(const char *, int) override { return true; } bool supports_readlink(const char *, char *, size_t) override { return true; } @@ -227,6 +228,7 @@ class Libc::Vfs_plugin : public Libc::Plugin return open(path, flags, Libc::ANY_FD); } + int access(char const *, int) override; int close(Libc::File_descriptor *) override; int dup2(Libc::File_descriptor *, Libc::File_descriptor *) override; int fcntl(Libc::File_descriptor *, int, long) override; @@ -251,6 +253,10 @@ class Libc::Vfs_plugin : public Libc::Plugin }; +int Libc::Vfs_plugin::access(const char *path, int amode) { + return _root_dir.leaf_path(path) ? 0 : -1; } + + Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags, int libc_fd) {