1 #include "git-compat-util.h"
3 #include "chdir-notify.h"
9 struct chdir_notify_entry
{
11 chdir_notify_callback cb
;
13 struct list_head list
;
15 static LIST_HEAD(chdir_notify_entries
);
17 void chdir_notify_register(const char *name
,
18 chdir_notify_callback cb
,
21 struct chdir_notify_entry
*e
= xmalloc(sizeof(*e
));
25 list_add_tail(&e
->list
, &chdir_notify_entries
);
28 static void reparent_cb(const char *name
,
39 *path
= reparent_relative_path(old_cwd
, new_cwd
, tmp
);
43 trace_printf_key(&trace_setup_key
,
44 "setup: reparent %s to '%s'",
49 void chdir_notify_reparent(const char *name
, char **path
)
51 chdir_notify_register(name
, reparent_cb
, path
);
54 int chdir_notify(const char *new_cwd
)
56 struct strbuf old_cwd
= STRBUF_INIT
;
57 struct list_head
*pos
;
59 if (strbuf_getcwd(&old_cwd
) < 0)
61 if (chdir(new_cwd
) < 0) {
62 int saved_errno
= errno
;
63 strbuf_release(&old_cwd
);
68 trace_printf_key(&trace_setup_key
,
69 "setup: chdir from '%s' to '%s'",
70 old_cwd
.buf
, new_cwd
);
72 list_for_each(pos
, &chdir_notify_entries
) {
73 struct chdir_notify_entry
*e
=
74 list_entry(pos
, struct chdir_notify_entry
, list
);
75 e
->cb(e
->name
, old_cwd
.buf
, new_cwd
, e
->data
);
78 strbuf_release(&old_cwd
);
82 char *reparent_relative_path(const char *old_cwd
,
88 if (is_absolute_path(path
))
91 full
= xstrfmt("%s/%s", old_cwd
, path
);
92 ret
= xstrdup(remove_leading_path(full
, new_cwd
));