{"thread":{"id":"5886","subject":"[PATCH] atomic write for sideband remote messages","startedAt":"2006-10-11T15:49:15Z","lastAt":"2006-10-11T15:49:15Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"28607","messageId":"Pine.LNX.4.64.0610111127360.2435@xanadu.home","threadId":"5886","inReplyTo":null,"subject":"[PATCH] atomic write for sideband remote messages","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2006-10-11T15:49:15Z","receivedAt":"2006-10-11T15:49:15Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"It has been a few times that I ended up with such a confusing display:\n\n|remote: Generating pack...\n|remote: Done counting 17 objects.\n|remote: Result has 9 objects.\n|remote: Deltifying 9 objects.\n|remote:  100% (9/9) done\n|remote: Unpacking 9 objects\n|Total 9, written 9 (delta 8), reused 0 (delta 0)\n| 100% (9/9) done\n\nThe confusion can be avoided in most cases by writing the remote message \nin one go to prevent interleacing with local messages.  The buffer \ndeclaration has been moved inside recv_sideband() to avoid extra string \ncopies.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n\n---\n\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex 6dabdee..9177379 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -75,7 +75,7 @@ static int run_remote_archiver(const cha\n \t\tdie(\"git-archive: expected a flush\");\n \n \t/* Now, start reading from fd[0] and spit it out to stdout */\n-\trv = recv_sideband(\"archive\", fd[0], 1, 2, buf, sizeof(buf));\n+\trv = recv_sideband(\"archive\", fd[0], 1, 2);\n \tclose(fd[0]);\n \trv |= finish_connect(pid);\n \ndiff --git a/fetch-clone.c b/fetch-clone.c\nindex b632ca0..76b99af 100644\n--- a/fetch-clone.c\n+++ b/fetch-clone.c\n@@ -115,12 +115,10 @@ static pid_t setup_sideband(int sideband\n \t\tdie(\"%s: unable to fork off sideband demultiplexer\", me);\n \tif (!side_pid) {\n \t\t/* subprocess */\n-\t\tchar buf[LARGE_PACKET_MAX];\n-\n \t\tclose(fd[0]);\n \t\tif (xd[0] != xd[1])\n \t\t\tclose(xd[1]);\n-\t\tif (recv_sideband(me, xd[0], fd[1], 2, buf, sizeof(buf)))\n+\t\tif (recv_sideband(me, xd[0], fd[1], 2))\n \t\t\texit(1);\n \t\texit(0);\n \t}\ndiff --git a/sideband.c b/sideband.c\nindex 1b14ff8..277fa3c 100644\n--- a/sideband.c\n+++ b/sideband.c\n@@ -11,10 +11,13 @@ #include \"sideband.h\"\n  * stream, aka \"verbose\").  A message over band #3 is a signal that\n  * the remote died unexpectedly.  A flush() concludes the stream.\n  */\n-int recv_sideband(const char *me, int in_stream, int out, int err, char *buf, int bufsz)\n+int recv_sideband(const char *me, int in_stream, int out, int err)\n {\n+\tchar buf[7 + LARGE_PACKET_MAX + 1];\n+\tstrcpy(buf, \"remote:\");\n \twhile (1) {\n-\t\tint len = packet_read_line(in_stream, buf, bufsz);\n+\t\tint band, len;\n+\t\tlen\t= packet_read_line(in_stream, buf+7, LARGE_PACKET_MAX);\n \t\tif (len == 0)\n \t\t\tbreak;\n \t\tif (len < 1) {\n@@ -22,25 +25,26 @@ int recv_sideband(const char *me, int in\n \t\t\tsafe_write(err, buf, len);\n \t\t\treturn SIDEBAND_PROTOCOL_ERROR;\n \t\t}\n+\t\tband = buf[7] & 0xff;\n \t\tlen--;\n-\t\tswitch (buf[0] & 0xFF) {\n+\t\tswitch (band) {\n \t\tcase 3:\n-\t\t\tsafe_write(err, \"remote: \", 8);\n-\t\t\tsafe_write(err, buf+1, len);\n-\t\t\tsafe_write(err, \"\\n\", 1);\n+\t\t\tbuf[7] = ' ';\n+\t\t\tbuf[8+len] = '\\n';\n+\t\t\tsafe_write(err, buf, 8+len+1);\n \t\t\treturn SIDEBAND_REMOTE_ERROR;\n \t\tcase 2:\n-\t\t\tsafe_write(err, \"remote: \", 8);\n-\t\t\tsafe_write(err, buf+1, len);\n+\t\t\tbuf[7] = ' ';\n+\t\t\tsafe_write(err, buf, 8+len);\n \t\t\tcontinue;\n \t\tcase 1:\n-\t\t\tsafe_write(out, buf+1, len);\n+\t\t\tsafe_write(out, buf+8, len);\n \t\t\tcontinue;\n \t\tdefault:\n-\t\t\tlen = sprintf(buf + 1,\n+\t\t\tlen = sprintf(buf,\n \t\t\t\t      \"%s: protocol error: bad band #%d\\n\",\n-\t\t\t\t      me, buf[0] & 0xFF);\n-\t\t\tsafe_write(err, buf+1, len);\n+\t\t\t\t      me, band);\n+\t\t\tsafe_write(err, buf, len);\n \t\t\treturn SIDEBAND_PROTOCOL_ERROR;\n \t\t}\n \t}\ndiff --git a/sideband.h b/sideband.h\nindex 4872106..a84b691 100644\n--- a/sideband.h\n+++ b/sideband.h\n@@ -7,7 +7,7 @@ #define SIDEBAND_REMOTE_ERROR -1\n #define DEFAULT_PACKET_MAX 1000\n #define LARGE_PACKET_MAX 65520\n \n-int recv_sideband(const char *me, int in_stream, int out, int err, char *, int);\n+int recv_sideband(const char *me, int in_stream, int out, int err);\n ssize_t send_sideband(int fd, int band, const char *data, ssize_t sz, int packet_max);\n \n #endif\n"}]}