{"thread":{"id":"2904","subject":"[RFC] Add \"write-index\" hook","startedAt":"2005-12-21T23:56:14Z","lastAt":"2005-12-22T00:35:59Z","messageCount":2,"participants":["Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"13910","messageId":"Pine.LNX.4.63.0512220055050.13515@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2904","inReplyTo":null,"subject":"[RFC] Add \"write-index\" hook","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-12-21T23:56:14Z","receivedAt":"2005-12-21T23:56:14Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nThis is a less hacky way to prevent index access than what I suggested\nearlier. It has the additional benefit that you can control access to\nthe index writing now.\n\nOh, and the code to run hooks (which die() on errors) has been refactored.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n\tWhile the use of this hook is questionable, I actually like the\n\trefactoring of the hooks, since it makes it so much easier\n\tto add new ones.\n\n index.c        |    7 ++++++\n receive-pack.c |   61 ++------------------------------------------------------\n run-command.c  |   49 +++++++++++++++++++++++++++++++++++++++++++++\n run-command.h  |    2 ++\n 4 files changed, 60 insertions(+), 59 deletions(-)\n\nd567efd0ccfb60ae03a81f02f819283767d69011\ndiff --git a/index.c b/index.c\nindex ad0eafe..3f6ca1e 100644\n--- a/index.c\n+++ b/index.c\n@@ -3,6 +3,7 @@\n  */\n #include <signal.h>\n #include \"cache.h\"\n+#include \"run-command.h\"\n \n static struct cache_file *cache_file_list;\n \n@@ -20,9 +21,15 @@ static void remove_lock_file_on_signal(i\n \tremove_lock_file();\n }\n \n+static char write_index_hook[] = \"hooks/write-index\";\n+\n int hold_index_file_for_update(struct cache_file *cf, const char *path)\n {\n \tint fd;\n+\n+\tif (run_hook(write_index_hook))\n+\t\treturn error(\"hook declined to write index\\n\");\n+\n \tsprintf(cf->lockfile, \"%s.lock\", path);\n \tfd = open(cf->lockfile, O_RDWR | O_CREAT | O_EXCL, 0666);\n \tif (fd >=0 && !cf->next) {\ndiff --git a/receive-pack.c b/receive-pack.c\nindex cbe37e7..d52d793 100644\n--- a/receive-pack.c\n+++ b/receive-pack.c\n@@ -59,36 +59,6 @@ static int verify_old_ref(const char *na\n \n static char update_hook[] = \"hooks/update\";\n \n-static int run_update_hook(const char *refname,\n-\t\t\t   char *old_hex, char *new_hex)\n-{\n-\tint code;\n-\n-\tif (access(update_hook, X_OK) < 0)\n-\t\treturn 0;\n-\tcode = run_command(update_hook, refname, old_hex, new_hex, NULL);\n-\tswitch (code) {\n-\tcase 0:\n-\t\treturn 0;\n-\tcase -ERR_RUN_COMMAND_FORK:\n-\t\tdie(\"hook fork failed\");\n-\tcase -ERR_RUN_COMMAND_EXEC:\n-\t\tdie(\"hook execute failed\");\n-\tcase -ERR_RUN_COMMAND_WAITPID:\n-\t\tdie(\"waitpid failed\");\n-\tcase -ERR_RUN_COMMAND_WAITPID_WRONG_PID:\n-\t\tdie(\"waitpid is confused\");\n-\tcase -ERR_RUN_COMMAND_WAITPID_SIGNAL:\n-\t\tfprintf(stderr, \"%s died of signal\", update_hook);\n-\t\treturn -1;\n-\tcase -ERR_RUN_COMMAND_WAITPID_NOEXIT:\n-\t\tdie(\"%s died strangely\", update_hook);\n-\tdefault:\n-\t\terror(\"%s exited with error code %d\", update_hook, -code);\n-\t\treturn -code;\n-\t}\n-}\n-\n static int update(const char *name,\n \t\t  unsigned char *old_sha1, unsigned char *new_sha1)\n {\n@@ -133,7 +103,7 @@ static int update(const char *name,\n \t\tunlink(lock_name);\n \t\treturn error(\"%s changed during push\", name);\n \t}\n-\tif (run_update_hook(name, old_hex, new_hex)) {\n+\tif (run_hook(update_hook, name, old_hex, new_hex)) {\n \t\tunlink(lock_name);\n \t\treturn error(\"hook declined to update %s\\n\", name);\n \t}\n@@ -149,33 +119,6 @@ static int update(const char *name,\n \n static char update_post_hook[] = \"hooks/post-update\";\n \n-static void run_update_post_hook(struct command *cmd)\n-{\n-\tstruct command *cmd_p;\n-\tint argc;\n-\tchar **argv;\n-\n-\tif (access(update_post_hook, X_OK) < 0)\n-\t\treturn;\n-\tfor (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {\n-\t\tif (!cmd_p->updated)\n-\t\t\tcontinue;\n-\t\targc++;\n-\t}\n-\targv = xmalloc(sizeof(*argv) * (1 + argc));\n-\targv[0] = update_post_hook;\n-\n-\tfor (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {\n-\t\tif (!cmd_p->updated)\n-\t\t\tcontinue;\n-\t\targv[argc] = xmalloc(strlen(cmd_p->ref_name) + 1);\n-\t\tstrcpy(argv[argc], cmd_p->ref_name);\n-\t\targc++;\n-\t}\n-\targv[argc] = NULL;\n-\trun_command_v_opt(argc, argv, RUN_COMMAND_NO_STDIO);\n-}\n-\n /*\n  * This gets called after(if) we've successfully\n  * unpacked the data payload.\n@@ -189,7 +132,7 @@ static void execute_commands(void)\n \t\t\t\t       cmd->old_sha1, cmd->new_sha1);\n \t\tcmd = cmd->next;\n \t}\n-\trun_update_post_hook(commands);\n+\trun_hook(update_post_hook, commands);\n }\n \n static void read_head_info(void)\ndiff --git a/run-command.c b/run-command.c\nindex 8bf5922..95455ef 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -67,3 +67,52 @@ int run_command(const char *cmd, ...)\n \t\treturn error(\"too many args to run %s\", cmd);\n \treturn run_command_v_opt(argc, argv, 0);\n }\n+\n+int run_hook(const char* hook, ...)\n+{\n+\tint argc;\n+\tchar *argv[MAX_RUN_COMMAND_ARGS];\n+\tconst char *arg;\n+\tva_list param;\n+\tint code;\n+\n+\tif (access(hook, X_OK) < 0)\n+\t\treturn 0;\n+\n+\tva_start(param, hook);\n+\targv[0] = (char*) hook;\n+\targc = 1;\n+\twhile (argc < MAX_RUN_COMMAND_ARGS) {\n+\t\targ = argv[argc++] = va_arg(param, char *);\n+\t\tif (!arg)\n+\t\t\tbreak;\n+\t}\n+\tva_end(param);\n+\tif (MAX_RUN_COMMAND_ARGS <= argc)\n+\t\treturn error(\"too many args to run %s\", hook);\n+\n+\tcode = run_command_v_opt(argc, argv, 0);\n+\n+\tswitch (code) {\n+\tcase 0:\n+\t\treturn 0;\n+\tcase -ERR_RUN_COMMAND_FORK:\n+\t\tdie(\"hook fork failed\");\n+\tcase -ERR_RUN_COMMAND_EXEC:\n+\t\tdie(\"hook execute failed\");\n+\tcase -ERR_RUN_COMMAND_WAITPID:\n+\t\tdie(\"waitpid failed\");\n+\tcase -ERR_RUN_COMMAND_WAITPID_WRONG_PID:\n+\t\tdie(\"waitpid is confused\");\n+\tcase -ERR_RUN_COMMAND_WAITPID_SIGNAL:\n+\t\tfprintf(stderr, \"%s died of signal\", hook);\n+\t\treturn -1;\n+\tcase -ERR_RUN_COMMAND_WAITPID_NOEXIT:\n+\t\tdie(\"%s died strangely\", hook);\n+\tdefault:\n+\t\terror(\"%s exited with error code %d\", hook, -code);\n+\t\treturn -code;\n+\t}\n+}\n+\n+\ndiff --git a/run-command.h b/run-command.h\nindex 2469eea..604176f 100644\n--- a/run-command.h\n+++ b/run-command.h\n@@ -16,5 +16,7 @@ enum {\n int run_command_v_opt(int argc, char **argv, int opt);\n int run_command_v(int argc, char **argv);\n int run_command(const char *cmd, ...);\n+/* unlike run_command(), run_hook die()s on errors */\n+int run_hook(const char *hook, ...);\n \n #endif\n-- \n1.0.0\n"},{"id":"13914","messageId":"Pine.LNX.4.63.0512220134170.14582@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2904","inReplyTo":"Pine.LNX.4.63.0512220055050.13515@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [RFC] Add \"write-index\" hook","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-12-22T00:35:59Z","receivedAt":"2005-12-22T00:35:59Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nthere is an obvious bug in this patch: both calls to run_hook() have to \nhave a final NULL argument.\n\nCiao,\nDscho\n\nP.S.: The reason I did not find this earlier was that I had hooks \ninstalled, but they were not executable, and thus did not get executed. \nD'oh!\n"}]}