Git fork
at reftables-rust 96 lines 1.9 kB view raw
1#include "git-compat-util.h" 2#include "abspath.h" 3#include "chdir-notify.h" 4#include "list.h" 5#include "path.h" 6#include "strbuf.h" 7#include "trace.h" 8 9struct chdir_notify_entry { 10 const char *name; 11 chdir_notify_callback cb; 12 void *data; 13 struct list_head list; 14}; 15static LIST_HEAD(chdir_notify_entries); 16 17void chdir_notify_register(const char *name, 18 chdir_notify_callback cb, 19 void *data) 20{ 21 struct chdir_notify_entry *e = xmalloc(sizeof(*e)); 22 e->name = name; 23 e->cb = cb; 24 e->data = data; 25 list_add_tail(&e->list, &chdir_notify_entries); 26} 27 28static void reparent_cb(const char *name, 29 const char *old_cwd, 30 const char *new_cwd, 31 void *data) 32{ 33 char **path = data; 34 char *tmp = *path; 35 36 if (!tmp) 37 return; 38 39 *path = reparent_relative_path(old_cwd, new_cwd, tmp); 40 free(tmp); 41 42 if (name) { 43 trace_printf_key(&trace_setup_key, 44 "setup: reparent %s to '%s'", 45 name, *path); 46 } 47} 48 49void chdir_notify_reparent(const char *name, char **path) 50{ 51 chdir_notify_register(name, reparent_cb, path); 52} 53 54int chdir_notify(const char *new_cwd) 55{ 56 struct strbuf old_cwd = STRBUF_INIT; 57 struct list_head *pos; 58 59 if (strbuf_getcwd(&old_cwd) < 0) 60 return -1; 61 if (chdir(new_cwd) < 0) { 62 int saved_errno = errno; 63 strbuf_release(&old_cwd); 64 errno = saved_errno; 65 return -1; 66 } 67 68 trace_printf_key(&trace_setup_key, 69 "setup: chdir from '%s' to '%s'", 70 old_cwd.buf, new_cwd); 71 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); 76 } 77 78 strbuf_release(&old_cwd); 79 return 0; 80} 81 82char *reparent_relative_path(const char *old_cwd, 83 const char *new_cwd, 84 const char *path) 85{ 86 char *ret, *full; 87 88 if (is_absolute_path(path)) 89 return xstrdup(path); 90 91 full = xstrfmt("%s/%s", old_cwd, path); 92 ret = xstrdup(remove_leading_path(full, new_cwd)); 93 free(full); 94 95 return ret; 96}