@matheusbsbs / matheus-bagliano / commits / 466dbc42f5
Fork 0

receive-pack: Send internal errors over side-band #2

If the client has requested side-band-64k capability, send any of the internal error or warning messages in the muxed side-band stream using the same band as our hook output, band #2. By putting everything in one stream we ensure all messages are processed by the side-band demuxer, avoiding interleaving between our own stderr and the side-band demuxer's stderr buffers. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shawn O. Pearce committed Feb 10, 2010 at 09:34 UTC 466dbc42f58623d4341d6b1171b5cc13e2b700df
2 files changed +52 -15
builtin-receive-pack.c
+50 -14
@@ -139,6 +139,42 @@ static struct command *commands;
139 static const char pre_receive_hook[] = "hooks/pre-receive";
140 static const char post_receive_hook[] = "hooks/post-receive";
141
142 +static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
143 +static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
144 +
145 +static void report_message(const char *prefix, const char *err, va_list params)
146 +{
147 + int sz = strlen(prefix);
148 + char msg[4096];
149 +
150 + strncpy(msg, prefix, sz);
151 + sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
152 + if (sz > (sizeof(msg) - 1))
153 + sz = sizeof(msg) - 1;
154 + msg[sz++] = '\n';
155 +
156 + if (use_sideband)
157 + send_sideband(1, 2, msg, sz, use_sideband);
158 + else
159 + xwrite(2, msg, sz);
160 +}
161 +
162 +static void rp_warning(const char *err, ...)
163 +{
164 + va_list params;
165 + va_start(params, err);
166 + report_message("warning: ", err, params);
167 + va_end(params);
168 +}
169 +
170 +static void rp_error(const char *err, ...)
171 +{
172 + va_list params;
173 + va_start(params, err);
174 + report_message("error: ", err, params);
175 + va_end(params);
176 +}
177 +
178 static int copy_to_sideband(int in, int out, void *arg)
179 {
180 char data[128];
@@ -276,7 +312,7 @@ static void warn_unconfigured_deny(void)
312 {
313 int i;
314 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
279 - warning("%s", warn_unconfigured_deny_msg[i]);
315 + rp_warning("%s", warn_unconfigured_deny_msg[i]);
316 }
317
318 static char *warn_unconfigured_deny_delete_current_msg[] = {
@@ -302,7 +338,7 @@ static void warn_unconfigured_deny_delete_current(void)
338 for (i = 0;
339 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
340 i++)
305 - warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
341 + rp_warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
342 }
343
344 static const char *update(struct command *cmd)
@@ -314,7 +350,7 @@ static const char *update(struct command *cmd)
350
351 /* only refs/... are allowed */
352 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
317 - error("refusing to create funny ref '%s' remotely", name);
353 + rp_error("refusing to create funny ref '%s' remotely", name);
354 return "funny refname";
355 }
356
@@ -324,12 +360,12 @@ static const char *update(struct command *cmd)
360 break;
361 case DENY_UNCONFIGURED:
362 case DENY_WARN:
327 - warning("updating the current branch");
363 + rp_warning("updating the current branch");
364 if (deny_current_branch == DENY_UNCONFIGURED)
365 warn_unconfigured_deny();
366 break;
367 case DENY_REFUSE:
332 - error("refusing to update checked out branch: %s", name);
368 + rp_error("refusing to update checked out branch: %s", name);
369 return "branch is currently checked out";
370 }
371 }
@@ -342,7 +378,7 @@ static const char *update(struct command *cmd)
378
379 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
380 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
345 - error("denying ref deletion for %s", name);
381 + rp_error("denying ref deletion for %s", name);
382 return "deletion prohibited";
383 }
384
@@ -354,10 +390,10 @@ static const char *update(struct command *cmd)
390 case DENY_UNCONFIGURED:
391 if (deny_delete_current == DENY_UNCONFIGURED)
392 warn_unconfigured_deny_delete_current();
357 - warning("deleting the current branch");
393 + rp_warning("deleting the current branch");
394 break;
395 case DENY_REFUSE:
360 - error("refusing to delete the current branch: %s", name);
396 + rp_error("refusing to delete the current branch: %s", name);
397 return "deletion of the current branch prohibited";
398 }
399 }
@@ -387,23 +423,23 @@ static const char *update(struct command *cmd)
423 break;
424 free_commit_list(bases);
425 if (!ent) {
390 - error("denying non-fast-forward %s"
391 - " (you should pull first)", name);
426 + rp_error("denying non-fast-forward %s"
427 + " (you should pull first)", name);
428 return "non-fast-forward";
429 }
430 }
431 if (run_update_hook(cmd)) {
396 - error("hook declined to update %s", name);
432 + rp_error("hook declined to update %s", name);
433 return "hook declined";
434 }
435
436 if (is_null_sha1(new_sha1)) {
437 if (!parse_object(old_sha1)) {
402 - warning ("Allowing deletion of corrupt ref.");
438 + rp_warning("Allowing deletion of corrupt ref.");
439 old_sha1 = NULL;
440 }
441 if (delete_ref(name, old_sha1, 0)) {
406 - error("failed to delete %s", name);
442 + rp_error("failed to delete %s", name);
443 return "failed to delete";
444 }
445 return NULL; /* good */
@@ -411,7 +447,7 @@ static const char *update(struct command *cmd)
447 else {
448 lock = lock_any_ref_for_update(name, old_sha1, 0);
449 if (!lock) {
414 - error("failed to lock %s", name);
450 + rp_error("failed to lock %s", name);
451 return "failed to lock";
452 }
453 if (write_ref_sha1(lock, new_sha1, "push")) {
t/t5401-update-hooks.sh
+2 -1
@@ -124,6 +124,7 @@ remote: STDOUT update refs/heads/master
124 remote: STDERR update refs/heads/master
125 remote: STDOUT update refs/heads/tofail
126 remote: STDERR update refs/heads/tofail
127 +remote: error: hook declined to update refs/heads/tofail
128 remote: STDOUT post-receive
129 remote: STDERR post-receive
130 remote: STDOUT post-update
@@ -131,7 +132,7 @@ remote: STDERR post-update
132 EOF
133 test_expect_success 'send-pack stderr contains hook messages' '
134 grep ^remote: send.err | sed "s/ *\$//" >actual &&
134 - test_cmp - actual <expect
135 + test_cmp expect actual
136 '
137
138 test_done