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
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

94 lignes
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. }