]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: port things dirname_malloc() → path_extract_directory()
authorLennart Poettering <lennart@poettering.net>
Mon, 22 Aug 2022 10:34:34 +0000 (12:34 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 23 Aug 2022 13:10:15 +0000 (15:10 +0200)
20 files changed:
src/analyze/analyze-verify-util.c
src/basic/mkdir.c
src/boot/bless-boot.c
src/core/automount.c
src/core/execute.c
src/core/mount.c
src/core/unit.c
src/dissect/dissect.c
src/home/homed-home.c
src/home/homework-luks.c
src/import/export-raw.c
src/libsystemd/sd-bus/bus-kernel.c
src/libsystemd/sd-bus/test-bus-watch-bind.c
src/libsystemd/sd-journal/sd-journal.c
src/machine/machine-dbus.c
src/shared/find-esp.c
src/shared/install.c
src/systemctl/systemctl-edit.c
src/systemctl/systemctl-show.c
src/test/test-bpf-devices.c

index 531144ba57d47664013f3c50c42f4143999245d7..c309c075163686acde63479a91cd91e2e64eb6fc 100644 (file)
@@ -61,9 +61,9 @@ int verify_prepare_filename(const char *filename, char **ret) {
                         return r;
         }
 
-        dir = dirname_malloc(abspath);
-        if (!dir)
-                return -ENOMEM;
+        r = path_extract_directory(abspath, &dir);
+        if (r < 0)
+                return r;
 
         c = path_join(dir, with_instance ?: name);
         if (!c)
@@ -73,24 +73,30 @@ int verify_prepare_filename(const char *filename, char **ret) {
         return 0;
 }
 
-int verify_generate_path(char **var, char **filenames) {
+int verify_generate_path(char **ret, char **filenames) {
         _cleanup_strv_free_ char **ans = NULL;
+        _cleanup_free_ char *joined = NULL;
         const char *old;
         int r;
 
         STRV_FOREACH(filename, filenames) {
+                _cleanup_free_ char *a = NULL;
                 char *t;
 
-                t = dirname_malloc(*filename);
-                if (!t)
-                        return -ENOMEM;
+                r = path_make_absolute_cwd(*filename, &a);
+                if (r < 0)
+                        return r;
+
+                r = path_extract_directory(a, &t);
+                if (r < 0)
+                        return r;
 
                 r = strv_consume(&ans, t);
                 if (r < 0)
                         return r;
         }
 
-        assert_se(strv_uniq(ans));
+        strv_uniq(ans);
 
         /* First, prepend our directories. Second, if some path was specified, use that, and
          * otherwise use the defaults. Any duplicates will be filtered out in path-lookup.c.
@@ -106,10 +112,11 @@ int verify_generate_path(char **var, char **filenames) {
                         return r;
         }
 
-        *var = strv_join(ans, ":");
-        if (!*var)
+        joined = strv_join(ans, ":");
+        if (!joined)
                 return -ENOMEM;
 
+        *ret = TAKE_PTR(joined);
         return 0;
 }
 
index d2c6b96a38d66e801863c1302d3364b543d844dd..8e4849b7926c07504d3e8140c05f13a4cced6a9e 100644 (file)
@@ -191,34 +191,37 @@ int mkdir_p_safe(const char *prefix, const char *path, mode_t mode, uid_t uid, g
 }
 
 int mkdir_p_root(const char *root, const char *p, uid_t uid, gid_t gid, mode_t m) {
-        _cleanup_free_ char *pp = NULL;
+        _cleanup_free_ char *pp = NULL, *bn = NULL;
         _cleanup_close_ int dfd = -1;
-        const char *bn;
         int r;
 
-        pp = dirname_malloc(p);
-        if (!pp)
-                return -ENOMEM;
-
-        /* Not top-level? */
-        if (!(path_equal(pp, "/") || isempty(pp) || path_equal(pp, "."))) {
-
-                /* Recurse up */
+        r = path_extract_directory(p, &pp);
+        if (r == -EDESTADDRREQ) {
+                /* only fname is passed, no prefix to operate on */
+                dfd = open(".", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+                if (dfd < 0)
+                        return -errno;
+        } else if (r == -EADDRNOTAVAIL)
+                /* only root dir or "." was passed, i.e. there is no parent to extract, in that case there's nothing to do. */
+                return 0;
+        else if (r < 0)
+                return r;
+        else {
+                /* Extracting the parent dir worked, hence we aren't top-level? Recurse up first. */
                 r = mkdir_p_root(root, pp, uid, gid, m);
                 if (r < 0)
                         return r;
+
+                dfd = chase_symlinks_and_open(pp, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_DIRECTORY, NULL);
+                if (dfd < 0)
+                        return dfd;
         }
 
-        bn = basename(p);
-        if (path_equal(bn, "/") || isempty(bn) || path_equal(bn, "."))
+        r = path_extract_filename(p, &bn);
+        if (r == -EADDRNOTAVAIL) /* Already top-level */
                 return 0;
-
-        if (!filename_is_valid(bn))
-                return -EINVAL;
-
-        dfd = chase_symlinks_and_open(pp, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_DIRECTORY, NULL);
-        if (dfd < 0)
-                return dfd;
+        if (r < 0)
+                return r;
 
         if (mkdirat(dfd, bn, m) < 0) {
                 if (errno == EEXIST)
index 315a1a37edb529a1ef88b6500b7e28e24963b63e..a0f347bddf57f345dd7dbc83f2b9e18b8c19474b 100644 (file)
@@ -399,7 +399,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
 }
 
 static int verb_set(int argc, char *argv[], void *userdata) {
-        _cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL, *parent = NULL;
+        _cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
         const char *target, *source1, *source2;
         uint64_t done;
         int r;
@@ -463,22 +463,18 @@ static int verb_set(int argc, char *argv[], void *userdata) {
 
                                 /* We found none of the snippets here, try the next directory */
                                 continue;
-                        } else if (r < 0)
+                        }
+                        if (r < 0)
                                 return log_error_errno(r, "Failed to rename '%s' to '%s': %m", source2, target);
-                        else
-                                log_debug("Successfully renamed '%s' to '%s'.", source2, target);
 
+                        log_debug("Successfully renamed '%s' to '%s'.", source2, target);
                 } else if (r < 0)
                         return log_error_errno(r, "Failed to rename '%s' to '%s': %m", source1, target);
                 else
                         log_debug("Successfully renamed '%s' to '%s'.", source1, target);
 
                 /* First, fsync() the directory these files are located in */
-                parent = dirname_malloc(target);
-                if (!parent)
-                        return log_oom();
-
-                r = fsync_path_at(fd, skip_slash(parent));
+                r = fsync_parent_at(fd, skip_slash(target));
                 if (r < 0)
                         log_debug_errno(errno, "Failed to synchronize image directory, ignoring: %m");
 
index 5adec9e966cc0fbbeb676d6f375c83faa09850a1..39c716fb8122c8eef8f7fc39290354370d42af19 100644 (file)
@@ -134,12 +134,13 @@ static int automount_add_trigger_dependencies(Automount *a) {
 
 static int automount_add_mount_dependencies(Automount *a) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(a);
 
-        parent = dirname_malloc(a->where);
-        if (!parent)
-                return -ENOMEM;
+        r = path_extract_directory(a->where, &parent);
+        if (r < 0)
+                return r;
 
         return unit_require_mounts_for(UNIT(a), parent, UNIT_DEPENDENCY_IMPLICIT);
 }
index e68d23173931fe9b118b5df15648baa5b22146fa..0ce18159bd22b9a64f0bb0997fc7875393df965f 100644 (file)
@@ -3104,9 +3104,9 @@ static int setup_credentials_internal(
                 /* If we do not have our own mount put used the plain directory fallback, then we need to
                  * open access to the top-level credential directory and the per-service directory now */
 
-                parent = dirname_malloc(final);
-                if (!parent)
-                        return -ENOMEM;
+                r = path_extract_directory(final, &parent);
+                if (r < 0)
+                        return r;
                 if (chmod(parent, 0755) < 0)
                         return -errno;
         }
index 9dd9fe1293f6b0adbbb07d7e87fb89385b52cfc6..52acd4345b528ec33843b01283017a053f557a85 100644 (file)
@@ -303,9 +303,9 @@ static int mount_add_mount_dependencies(Mount *m) {
 
                 /* Adds in links to other mount points that might lie further up in the hierarchy */
 
-                parent = dirname_malloc(m->where);
-                if (!parent)
-                        return -ENOMEM;
+                r = path_extract_directory(m->where, &parent);
+                if (r < 0)
+                        return r;
 
                 r = unit_require_mounts_for(UNIT(m), parent, UNIT_DEPENDENCY_IMPLICIT);
                 if (r < 0)
index 0798c29c9d469f3a1f5038866a38154c64db74af..6242f045b430739bc57f43f30106865dea5ec45f 100644 (file)
@@ -594,12 +594,10 @@ static void unit_remove_transient(Unit *u) {
         STRV_FOREACH(i, u->dropin_paths) {
                 _cleanup_free_ char *p = NULL, *pp = NULL;
 
-                p = dirname_malloc(*i); /* Get the drop-in directory from the drop-in file */
-                if (!p)
+                if (path_extract_directory(*i, &p) < 0) /* Get the drop-in directory from the drop-in file */
                         continue;
 
-                pp = dirname_malloc(p); /* Get the config directory from the drop-in directory */
-                if (!pp)
+                if (path_extract_directory(p, &pp) < 0) /* Get the config directory from the drop-in directory */
                         continue;
 
                 /* Only drop transient drop-ins */
index d9f3fab835be32e1b4dfa696390ed1dad8b368c0..4ae24e7153616630910e3ce4fb32d2a4eb4f25ec 100644 (file)
@@ -791,9 +791,9 @@ static int action_copy(DissectedImage *m, LoopDevice *d) {
 
                 assert(arg_action == ACTION_COPY_TO);
 
-                dn = dirname_malloc(arg_target);
-                if (!dn)
-                        return log_oom();
+                r = path_extract_directory(arg_target, &dn);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract directory name from target path '%s': %m", arg_target);
 
                 r = chase_symlinks(dn, mounted_dir, CHASE_PREFIX_ROOT|CHASE_WARN, NULL, &dfd);
                 if (r < 0)
index 1d8ededcaecdf6acf4f06232656319e69915b532..8a389f721638853d677dc31f3d25f740686e767a 100644 (file)
@@ -2176,9 +2176,9 @@ static int home_get_disk_status_luks(
                                 disk_size = st.st_size;
                                 stat_used = st.st_blocks * 512;
 
-                                parent = dirname_malloc(ip);
-                                if (!parent)
-                                        return log_oom();
+                                r = path_extract_directory(ip, &parent);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to extract parent directory from image path '%s': %m", ip);
 
                                 if (statfs(parent, &sfs) < 0)
                                         log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", parent);
index 5f3e79a67aad8aca168f774c5229a48522b0592b..c83292df7d3ae63ebee21d7b6368b7d5c659e5dc 100644 (file)
@@ -1989,10 +1989,11 @@ static int wait_for_devlink(const char *path) {
                                 return log_error_errno(errno, "Failed to allocate inotify fd: %m");
                 }
 
-                dn = dirname_malloc(path);
+                r = path_extract_directory(path, &dn);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract directory from device node path '%s': %m", path);
                 for (;;) {
-                        if (!dn)
-                                return log_oom();
+                        _cleanup_free_ char *ndn = NULL;
 
                         log_info("Watching %s", dn);
 
@@ -2002,10 +2003,13 @@ static int wait_for_devlink(const char *path) {
                         } else
                                 break;
 
-                        if (empty_or_root(dn))
+                        r = path_extract_directory(dn, &ndn);
+                        if (r == -EADDRNOTAVAIL) /* Arrived at the top? */
                                 break;
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to extract directory from device node path '%s': %m", dn);
 
-                        dn = dirname_malloc(dn);
+                        free_and_replace(dn, ndn);
                 }
 
                 w = now(CLOCK_MONOTONIC);
index 6617a9c9b673530c02f42869db224f9a6a241527..a3ff6a393410ef40b07ed79dba86df425d19d704 100644 (file)
@@ -2,12 +2,6 @@
 
 #include <sys/sendfile.h>
 
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the POSIX
- * version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
 #include "sd-daemon.h"
 
 #include "alloc-util.h"
index cba1ab2953382a81ff6ffc8e9cb7b1862e61de31..b553f153968899cfe5f48d67871b420151c30f15 100644 (file)
@@ -9,12 +9,6 @@
 #include <sys/mman.h>
 #include <sys/prctl.h>
 
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the POSIX
- * version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
 #include "alloc-util.h"
 #include "bus-internal.h"
 #include "bus-kernel.h"
index fdc8772f84180ba179a48ac8712a071852fb222b..6e522ae54becaadb6fc59fcb45db4d6307d99b04 100644 (file)
@@ -53,8 +53,7 @@ static void* thread_server(void *p) {
         assert_se(mkdir_parents(path, 0755) >= 0);
         (void) usleep(100 * USEC_PER_MSEC);
 
-        d = dirname_malloc(path);
-        assert_se(d);
+        assert_se(path_extract_directory(path, &d) >= 0);
         assert_se(asprintf(&suffixed, "%s.%" PRIx64, d, random_u64()) >= 0);
         assert_se(rename(d, suffixed) >= 0);
         (void) usleep(100 * USEC_PER_MSEC);
index 2a46f11d8ad87aeba3806aeefa2490187a33f5d7..77d03ec95ff3c67399c2e7ada025da28afc8dbba 100644 (file)
@@ -1858,9 +1858,9 @@ static int add_current_paths(sd_journal *j) {
                 _cleanup_free_ char *dir = NULL;
                 int r;
 
-                dir = dirname_malloc(f->path);
-                if (!dir)
-                        return -ENOMEM;
+                r = path_extract_directory(f->path, &dir);
+                if (r < 0)
+                        return r;
 
                 r = add_directory(j, dir, NULL);
                 if (r < 0)
index bd203b37dd291c058159be27d04978341615f15c..87d04c3d5805ad77bc0e555d9529c3a62ef80c77 100644 (file)
@@ -4,12 +4,6 @@
 #include <sys/mount.h>
 #include <sys/wait.h>
 
-/* When we include libgen.h because we need dirname() we immediately
- * undefine basename() since libgen.h defines it as a macro to the POSIX
- * version which is really broken. We prefer GNU basename(). */
-#include <libgen.h>
-#undef basename
-
 #include "alloc-util.h"
 #include "bus-common-errors.h"
 #include "bus-get-properties.h"
@@ -902,7 +896,8 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
 }
 
 int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        const char *src, *dest, *host_path, *container_path, *host_basename, *container_basename, *container_dirname;
+        _cleanup_free_ char *host_basename = NULL, *container_basename = NULL;
+        const char *src, *dest, *host_path, *container_path;
         _cleanup_close_pair_ int errno_pipe_fd[2] = { -1, -1 };
         CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS;
         _cleanup_close_ int hostfd = -1;
@@ -910,7 +905,6 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
         bool copy_from;
         pid_t child;
         uid_t uid_shift;
-        char *t;
         int r;
 
         assert(message);
@@ -984,11 +978,13 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
                 container_path = dest;
         }
 
-        host_basename = basename(host_path);
+        r = path_extract_filename(host_path, &host_basename);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", host_path);
 
-        container_basename = basename(container_path);
-        t = strdupa_safe(container_path);
-        container_dirname = dirname(t);
+        r = path_extract_filename(container_path, &container_basename);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", container_path);
 
         hostfd = open_parent(host_path, O_CLOEXEC, 0);
         if (hostfd < 0)
@@ -1019,9 +1015,9 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
                         goto child_fail;
                 }
 
-                containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
+                containerfd = open_parent(container_path, O_CLOEXEC, 0);
                 if (containerfd < 0) {
-                        r = log_error_errno(errno, "Failed to open destination directory: %m");
+                        r = log_error_errno(containerfd, "Failed to open destination directory: %m");
                         goto child_fail;
                 }
 
index 14c1ce0b45c163954c4b3361a9db83cabfb626c8..8a20fa7e47676a56b24632c70a816502799c7c15 100644 (file)
@@ -280,9 +280,9 @@ static int verify_fsroot_dir(
                          * directly instead. It's not as good, due to symlinks and such, but we can't do
                          * anything better here. */
 
-                        parent = dirname_malloc(path);
-                        if (!parent)
-                                return log_oom();
+                        r = path_extract_filename(path, &parent);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to extract parent path from '%s': %m", path);
 
                         r = RET_NERRNO(stat(parent, &st2));
                 }
index 5ae39f6a04e304f9792fa36a9a3b9d1fb5f1de2e..1a0a536080afd302083289c11bdaafe8771d4ab6 100644 (file)
@@ -102,12 +102,13 @@ DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(unit_file_type, UnitFileType);
 
 static int in_search_path(const LookupPaths *lp, const char *path) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(path);
 
-        parent = dirname_malloc(path);
-        if (!parent)
-                return -ENOMEM;
+        r = path_extract_directory(path, &parent);
+        if (r < 0)
+                return r;
 
         return path_strv_contains(lp->search_path, parent);
 }
@@ -135,13 +136,14 @@ static const char* skip_root(const char *root_dir, const char *path) {
 
 static int path_is_generator(const LookupPaths *lp, const char *path) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(lp);
         assert(path);
 
-        parent = dirname_malloc(path);
-        if (!parent)
-                return -ENOMEM;
+        r = path_extract_directory(path, &parent);
+        if (r < 0)
+                return r;
 
         return path_equal_ptr(parent, lp->generator) ||
                path_equal_ptr(parent, lp->generator_early) ||
@@ -150,26 +152,28 @@ static int path_is_generator(const LookupPaths *lp, const char *path) {
 
 static int path_is_transient(const LookupPaths *lp, const char *path) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(lp);
         assert(path);
 
-        parent = dirname_malloc(path);
-        if (!parent)
-                return -ENOMEM;
+        r = path_extract_directory(path, &parent);
+        if (r < 0)
+                return r;
 
         return path_equal_ptr(parent, lp->transient);
 }
 
 static int path_is_control(const LookupPaths *lp, const char *path) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(lp);
         assert(path);
 
-        parent = dirname_malloc(path);
-        if (!parent)
-                return -ENOMEM;
+        r = path_extract_directory(path, &parent);
+        if (r < 0)
+                return r;
 
         return path_equal_ptr(parent, lp->persistent_control) ||
                path_equal_ptr(parent, lp->runtime_control);
@@ -177,6 +181,7 @@ static int path_is_control(const LookupPaths *lp, const char *path) {
 
 static int path_is_config(const LookupPaths *lp, const char *path, bool check_parent) {
         _cleanup_free_ char *parent = NULL;
+        int r;
 
         assert(lp);
         assert(path);
@@ -185,9 +190,9 @@ static int path_is_config(const LookupPaths *lp, const char *path, bool check_pa
          * them we couldn't discern configuration from transient or generated units */
 
         if (check_parent) {
-                parent = dirname_malloc(path);
-                if (!parent)
-                        return -ENOMEM;
+                r = path_extract_directory(path, &parent);
+                if (r < 0)
+                        return r;
 
                 path = parent;
         }
@@ -199,6 +204,7 @@ static int path_is_config(const LookupPaths *lp, const char *path, bool check_pa
 static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_parent) {
         _cleanup_free_ char *parent = NULL;
         const char *rpath;
+        int r;
 
         assert(lp);
         assert(path);
@@ -211,9 +217,9 @@ static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_p
                 return true;
 
         if (check_parent) {
-                parent = dirname_malloc(path);
-                if (!parent)
-                        return -ENOMEM;
+                r = path_extract_directory(path, &parent);
+                if (r < 0)
+                        return r;
 
                 path = parent;
         }
@@ -1793,9 +1799,9 @@ int unit_file_verify_alias(
 
                 path_alias ++; /* skip over slash */
 
-                dir = dirname_malloc(dst);
-                if (!dir)
-                        return log_oom();
+                r = path_extract_directory(dst, &dir);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extract parent directory from '%s': %m", dst);
 
                 p = endswith(dir, ".wants");
                 if (!p)
index 446dfd7dd63e355e9786028951aa705a2cb3980d..a363d7a494a977d211f9e3f97510e45c20f4aa1f 100644 (file)
@@ -579,9 +579,9 @@ end:
                 if (!arg_full) {
                         _cleanup_free_ char *dir = NULL;
 
-                        dir = dirname_malloc(*original);
-                        if (!dir)
-                                return log_oom();
+                        r = path_extract_directory(*original, &dir);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to extract directory from '%s': %m", *original);
 
                         /* No need to check if the dir is empty, rmdir does nothing if it is not the case. */
                         (void) rmdir(dir);
index 36a0748c14ac0e2a0553acd43939ee8e516f99cf..beeffda316c48d713e152d6f5a3c5f5be387325a 100644 (file)
@@ -393,10 +393,10 @@ static void print_status_info(
 
                                 dir = mfree(dir);
 
-                                dir = dirname_malloc(*dropin);
-                                if (!dir) {
-                                        log_oom();
-                                        return;
+                                r = path_extract_directory(*dropin, &dir);
+                                if (r < 0) {
+                                        log_error_errno(r, "Failed to extract directory of '%s': %m", *dropin);
+                                        break;
                                 }
 
                                 printf("%s\n"
index 587591cf04858adbe90c34b16cde332b9ca6814e..e17548373413ae19869897d135601d0a6cc7acaa 100644 (file)
@@ -295,7 +295,7 @@ int main(int argc, char *argv[]) {
         test_policy_empty(false, cgroup, &prog);
         test_policy_empty(true, cgroup, &prog);
 
-        assert_se(parent = dirname_malloc(cgroup));
+        assert_se(path_extract_directory(cgroup, &parent) >= 0);
 
         assert_se(cg_mask_supported(&supported) >= 0);
         r = cg_attach_everywhere(supported, parent, 0, NULL, NULL);