diff options
author | Michal Schmidt <mschmidt@redhat.com> | 2013-03-06 19:28:55 +0100 |
---|---|---|
committer | Michal Schmidt <mschmidt@redhat.com> | 2013-03-08 10:58:51 +0100 |
commit | 180d6802e585e8a2826b76872438641b73e3fa6f (patch) | |
tree | 253d20cf0ffa84bb66f6c73ea449f102453d13d4 /src/core/path.c | |
parent | a740c14c59907f370a6b3a3ba5a86fada88cb07e (diff) |
path: avoid an allocation in path_spec_watch
No need for strdup. We can slice the path in place if we always undo it
afterwards.
Diffstat (limited to 'src/core/path.c')
-rw-r--r-- | src/core/path.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/src/core/path.c b/src/core/path.c index 01a2b0810e..295e5cdf0e 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -53,7 +53,6 @@ int path_spec_watch(PathSpec *s, Unit *u) { }; bool exists = false; - char _cleanup_free_ *path = NULL; char *slash, *oldslash = NULL; int r; @@ -62,10 +61,6 @@ int path_spec_watch(PathSpec *s, Unit *u) { path_spec_unwatch(s, u); - path = strdup(s->path); - if (!path) - return -ENOMEM; - s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); if (s->inotify_fd < 0) { r = -errno; @@ -78,25 +73,32 @@ int path_spec_watch(PathSpec *s, Unit *u) { /* This assumes the path was passed through path_kill_slashes()! */ - for(slash = strchr(path, '/'); ; slash = strchr(slash+1, '/')) { + for (slash = strchr(s->path, '/'); ; slash = strchr(slash+1, '/')) { + char *cut = NULL; int flags; char tmp; if (slash) { - tmp = slash[slash == path]; - slash[slash == path] = '\0'; + cut = slash + (slash == s->path); + tmp = *cut; + *cut = '\0'; + flags = IN_MOVE_SELF | IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO; - } else { + } else flags = flags_table[s->type]; - } - r = inotify_add_watch(s->inotify_fd, path, flags); + r = inotify_add_watch(s->inotify_fd, s->path, flags); if (r < 0) { - if (errno == EACCES || errno == ENOENT) + if (errno == EACCES || errno == ENOENT) { + if (cut) + *cut = tmp; break; + } - log_warning("Failed to add watch on %s: %m", path); + log_warning("Failed to add watch on %s: %m", s->path); r = -errno; + if (cut) + *cut = tmp; goto fail; } else { exists = true; @@ -104,29 +106,30 @@ int path_spec_watch(PathSpec *s, Unit *u) { /* Path exists, we don't need to watch parent too closely. */ if (oldslash) { - char tmp2 = oldslash[oldslash == path]; - oldslash[oldslash == path] = '\0'; + char *cut2 = oldslash + (oldslash == s->path); + char tmp2 = *cut2; + *cut2 = '\0'; - inotify_add_watch(s->inotify_fd, path, IN_MOVE_SELF); + inotify_add_watch(s->inotify_fd, s->path, IN_MOVE_SELF); /* Error is ignored, the worst can happen is we get spurious events. */ - oldslash[oldslash == path] = tmp2; + *cut2 = tmp2; } } - if (slash) { - slash[slash == path] = tmp; + if (cut) + *cut = tmp; + + if (slash) oldslash = slash; - } else { + else { /* whole path has been iterated over */ s->primary_wd = r; break; } } - assert(errno == EACCES || errno == ENOENT || streq(path, s->path)); - if (!exists) { log_error("Failed to add watch on any of the components of %s: %m", s->path); |