2 #include "chdir-notify.h"
6 struct chdir_notify_entry
{
8 chdir_notify_callback cb
;
10 struct list_head list
;
12 static LIST_HEAD(chdir_notify_entries
);
14 void chdir_notify_register(const char *name
,
15 chdir_notify_callback cb
,
18 struct chdir_notify_entry
*e
= xmalloc(sizeof(*e
));
22 list_add_tail(&e
->list
, &chdir_notify_entries
);
25 static void reparent_cb(const char *name
,
36 *path
= reparent_relative_path(old_cwd
, new_cwd
, tmp
);
40 trace_printf_key(&trace_setup_key
,
41 "setup: reparent %s to '%s'",
46 void chdir_notify_reparent(const char *name
, char **path
)
48 chdir_notify_register(name
, reparent_cb
, path
);
51 int chdir_notify(const char *new_cwd
)
53 struct strbuf old_cwd
= STRBUF_INIT
;
54 struct list_head
*pos
;
56 if (strbuf_getcwd(&old_cwd
) < 0)
58 if (chdir(new_cwd
) < 0) {
59 int saved_errno
= errno
;
60 strbuf_release(&old_cwd
);
65 trace_printf_key(&trace_setup_key
,
66 "setup: chdir from '%s' to '%s'",
67 old_cwd
.buf
, new_cwd
);
69 list_for_each(pos
, &chdir_notify_entries
) {
70 struct chdir_notify_entry
*e
=
71 list_entry(pos
, struct chdir_notify_entry
, list
);
72 e
->cb(e
->name
, old_cwd
.buf
, new_cwd
, e
->data
);
75 strbuf_release(&old_cwd
);
79 char *reparent_relative_path(const char *old_cwd
,
85 if (is_absolute_path(path
))
88 full
= xstrfmt("%s/%s", old_cwd
, path
);
89 ret
= xstrdup(remove_leading_path(full
, new_cwd
));