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:
parent
a740c14c59
commit
180d6802e5
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue