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.
This commit is contained in:
Michal Schmidt 2013-03-06 19:28:55 +01:00
parent a740c14c59
commit 180d6802e5

View file

@ -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);