THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

94 rindas
1.8KB

  1. #include "cache.h"
  2. #include "chdir-notify.h"
  3. #include "list.h"
  4. #include "strbuf.h"
  5. struct chdir_notify_entry {
  6. const char *name;
  7. chdir_notify_callback cb;
  8. void *data;
  9. struct list_head list;
  10. };
  11. static LIST_HEAD(chdir_notify_entries);
  12. void chdir_notify_register(const char *name,
  13. chdir_notify_callback cb,
  14. void *data)
  15. {
  16. struct chdir_notify_entry *e = xmalloc(sizeof(*e));
  17. e->name = name;
  18. e->cb = cb;
  19. e->data = data;
  20. list_add_tail(&e->list, &chdir_notify_entries);
  21. }
  22. static void reparent_cb(const char *name,
  23. const char *old_cwd,
  24. const char *new_cwd,
  25. void *data)
  26. {
  27. char **path = data;
  28. char *tmp = *path;
  29. if (!tmp)
  30. return;
  31. *path = reparent_relative_path(old_cwd, new_cwd, tmp);
  32. free(tmp);
  33. if (name) {
  34. trace_printf_key(&trace_setup_key,
  35. "setup: reparent %s to '%s'",
  36. name, *path);
  37. }
  38. }
  39. void chdir_notify_reparent(const char *name, char **path)
  40. {
  41. chdir_notify_register(name, reparent_cb, path);
  42. }
  43. int chdir_notify(const char *new_cwd)
  44. {
  45. struct strbuf old_cwd = STRBUF_INIT;
  46. struct list_head *pos;
  47. if (strbuf_getcwd(&old_cwd) < 0)
  48. return -1;
  49. if (chdir(new_cwd) < 0) {
  50. int saved_errno = errno;
  51. strbuf_release(&old_cwd);
  52. errno = saved_errno;
  53. return -1;
  54. }
  55. trace_printf_key(&trace_setup_key,
  56. "setup: chdir from '%s' to '%s'",
  57. old_cwd.buf, new_cwd);
  58. list_for_each(pos, &chdir_notify_entries) {
  59. struct chdir_notify_entry *e =
  60. list_entry(pos, struct chdir_notify_entry, list);
  61. e->cb(e->name, old_cwd.buf, new_cwd, e->data);
  62. }
  63. strbuf_release(&old_cwd);
  64. return 0;
  65. }
  66. char *reparent_relative_path(const char *old_cwd,
  67. const char *new_cwd,
  68. const char *path)
  69. {
  70. char *ret, *full;
  71. if (is_absolute_path(path))
  72. return xstrdup(path);
  73. full = xstrfmt("%s/%s", old_cwd, path);
  74. ret = xstrdup(remove_leading_path(full, new_cwd));
  75. free(full);
  76. return ret;
  77. }