summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Schmidt <mschmidt@redhat.com>2013-03-06 19:28:55 +0100
committerMichal Schmidt <mschmidt@redhat.com>2013-03-08 10:58:51 +0100
commit180d6802e585e8a2826b76872438641b73e3fa6f (patch)
tree253d20cf0ffa84bb66f6c73ea449f102453d13d4
parenta740c14c59907f370a6b3a3ba5a86fada88cb07e (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.
-rw-r--r--src/core/path.c47
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);