3 #include "chdir-notify.h"
7 struct chdir_notify_entry
{
9 chdir_notify_callback cb
;
11 struct list_head list
;
13 static LIST_HEAD(chdir_notify_entries
);
15 void chdir_notify_register(const char *name
,
16 chdir_notify_callback cb
,
19 struct chdir_notify_entry
*e
= xmalloc(sizeof(*e
));
23 list_add_tail(&e
->list
, &chdir_notify_entries
);
26 static void reparent_cb(const char *name
,
37 *path
= reparent_relative_path(old_cwd
, new_cwd
, tmp
);
41 trace_printf_key(&trace_setup_key
,
42 "setup: reparent %s to '%s'",
47 void chdir_notify_reparent(const char *name
, char **path
)
49 chdir_notify_register(name
, reparent_cb
, path
);
52 int chdir_notify(const char *new_cwd
)
54 struct strbuf old_cwd
= STRBUF_INIT
;
55 struct list_head
*pos
;
57 if (strbuf_getcwd(&old_cwd
) < 0)
59 if (chdir(new_cwd
) < 0) {
60 int saved_errno
= errno
;
61 strbuf_release(&old_cwd
);
66 trace_printf_key(&trace_setup_key
,
67 "setup: chdir from '%s' to '%s'",
68 old_cwd
.buf
, new_cwd
);
70 list_for_each(pos
, &chdir_notify_entries
) {
71 struct chdir_notify_entry
*e
=
72 list_entry(pos
, struct chdir_notify_entry
, list
);
73 e
->cb(e
->name
, old_cwd
.buf
, new_cwd
, e
->data
);
76 strbuf_release(&old_cwd
);
80 char *reparent_relative_path(const char *old_cwd
,
86 if (is_absolute_path(path
))
89 full
= xstrfmt("%s/%s", old_cwd
, path
);
90 ret
= xstrdup(remove_leading_path(full
, new_cwd
));