{"thread":{"id":"4279","subject":"Clean up sha1 file writing","startedAt":"2006-05-24T15:30:54Z","lastAt":"2006-06-04T19:05:32Z","messageCount":15,"participants":["Linus Torvalds","Matthias Lederhofer","Junio C Hamano","Sean","Jeff King","H. Peter Anvin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"20634","messageId":"Pine.LNX.4.64.0605240820560.5623@g5.osdl.org","threadId":"4279","inReplyTo":null,"subject":"Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-24T15:30:54Z","receivedAt":"2006-05-24T15:30:54Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThis cleans up and future-proofs the sha1 file writing in sha1_file.c.\n\nIn particular, instead of doing a simple \"write()\" call and just verifying \nthat it succeeds (or - as in one place - just assuming it does), it uses \n\"write_buffer()\" to write data to the file descriptor while correctly \nchecking for partial writes, EINTR etc.\n\nIt also splits up write_sha1_to_fd() to be a lot more readable: if we need \nto re-create the compressed object, we do so in a separate helper \nfunction, making the logic a whole lot more modular and obvious.\n\nSigned-off-by: Linus Torvalds <torvalds@osdl.org>\n---\n\nThis shouldn't change any behaviour, and it's obviously touching some core \ncode, so maybe it's not worth it. On the other hand, from a longer-term \nmaintenance standpoint and from a \"be much more careful when doing file \nwrites\" standpoint, I think it's worth it.\n\nThe re-write is \"obviously correct\" (famous last words) and is mostly \njust moving code around and getting rid of a few temporaries that become \nunnecessary as a result.\n\nThe patch looks a bit messy: the changes aren't actually that big, but the \nsplit-up and the resulting re-indentation makes the patch fairly \nunreadable, so the cleanups are more obvious when you look at the \nbefore-and-after side by side rather than when looking at the unified \ndiff..)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 2230010..c2fe7c2 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1399,6 +1399,25 @@ int move_temp_to_file(const char *tmpfil\n \treturn 0;\n }\n \n+static int write_buffer(int fd, const void *buf, size_t len)\n+{\n+\twhile (len) {\n+\t\tssize_t size;\n+\n+\t\tsize = write(fd, buf, len);\n+\t\tif (!size)\n+\t\t\treturn error(\"file write: disk full\");\n+\t\tif (size < 0) {\n+\t\t\tif (errno == EINTR || errno == EAGAIN)\n+\t\t\t\tcontinue;\n+\t\t\treturn error(\"file write error (%s)\", strerror(errno));\n+\t\t}\n+\t\tlen -= size;\n+\t\tbuf += size;\n+\t}\n+\treturn 0;\n+}\n+\n int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1)\n {\n \tint size;\n@@ -1465,8 +1484,8 @@ int write_sha1_file(void *buf, unsigned \n \tdeflateEnd(&stream);\n \tsize = stream.total_out;\n \n-\tif (write(fd, compressed, size) != size)\n-\t\tdie(\"unable to write file\");\n+\tif (write_buffer(fd, compressed, size) < 0)\n+\t\tdie(\"unable to write sha1 file\");\n \tfchmod(fd, 0444);\n \tclose(fd);\n \tfree(compressed);\n@@ -1474,73 +1493,70 @@ int write_sha1_file(void *buf, unsigned \n \treturn move_temp_to_file(tmpfile, filename);\n }\n \n-int write_sha1_to_fd(int fd, const unsigned char *sha1)\n+/*\n+ * We need to unpack and recompress the object for writing\n+ * it out to a different file.\n+ */\n+static void *repack_object(const unsigned char *sha1, unsigned long *objsize)\n {\n-\tssize_t size;\n-\tunsigned long objsize;\n-\tint posn = 0;\n-\tvoid *map = map_sha1_file_internal(sha1, &objsize);\n-\tvoid *buf = map;\n-\tvoid *temp_obj = NULL;\n+\tsize_t size;\n \tz_stream stream;\n+\tunsigned char *unpacked;\n+\tunsigned long len;\n+\tchar type[20];\n+\tchar hdr[50];\n+\tint hdrlen;\n+\tvoid *buf;\n \n-\tif (!buf) {\n-\t\tunsigned char *unpacked;\n-\t\tunsigned long len;\n-\t\tchar type[20];\n-\t\tchar hdr[50];\n-\t\tint hdrlen;\n-\t\t// need to unpack and recompress it by itself\n-\t\tunpacked = read_packed_sha1(sha1, type, &len);\n+\t// need to unpack and recompress it by itself\n+\tunpacked = read_packed_sha1(sha1, type, &len);\n \n-\t\thdrlen = sprintf(hdr, \"%s %lu\", type, len) + 1;\n+\thdrlen = sprintf(hdr, \"%s %lu\", type, len) + 1;\n \n-\t\t/* Set it up */\n-\t\tmemset(&stream, 0, sizeof(stream));\n-\t\tdeflateInit(&stream, Z_BEST_COMPRESSION);\n-\t\tsize = deflateBound(&stream, len + hdrlen);\n-\t\ttemp_obj = buf = xmalloc(size);\n+\t/* Set it up */\n+\tmemset(&stream, 0, sizeof(stream));\n+\tdeflateInit(&stream, Z_BEST_COMPRESSION);\n+\tsize = deflateBound(&stream, len + hdrlen);\n+\tbuf = xmalloc(size);\n \n-\t\t/* Compress it */\n-\t\tstream.next_out = buf;\n-\t\tstream.avail_out = size;\n+\t/* Compress it */\n+\tstream.next_out = buf;\n+\tstream.avail_out = size;\n \t\t\n-\t\t/* First header.. */\n-\t\tstream.next_in = (void *)hdr;\n-\t\tstream.avail_in = hdrlen;\n-\t\twhile (deflate(&stream, 0) == Z_OK)\n-\t\t\t/* nothing */;\n+\t/* First header.. */\n+\tstream.next_in = (void *)hdr;\n+\tstream.avail_in = hdrlen;\n+\twhile (deflate(&stream, 0) == Z_OK)\n+\t\t/* nothing */;\n \n-\t\t/* Then the data itself.. */\n-\t\tstream.next_in = unpacked;\n-\t\tstream.avail_in = len;\n-\t\twhile (deflate(&stream, Z_FINISH) == Z_OK)\n-\t\t\t/* nothing */;\n-\t\tdeflateEnd(&stream);\n-\t\tfree(unpacked);\n-\t\t\n-\t\tobjsize = stream.total_out;\n-\t}\n+\t/* Then the data itself.. */\n+\tstream.next_in = unpacked;\n+\tstream.avail_in = len;\n+\twhile (deflate(&stream, Z_FINISH) == Z_OK)\n+\t\t/* nothing */;\n+\tdeflateEnd(&stream);\n+\tfree(unpacked);\n \n-\tdo {\n-\t\tsize = write(fd, buf + posn, objsize - posn);\n-\t\tif (size <= 0) {\n-\t\t\tif (!size) {\n-\t\t\t\tfprintf(stderr, \"write closed\\n\");\n-\t\t\t} else {\n-\t\t\t\tperror(\"write \");\n-\t\t\t}\n-\t\t\treturn -1;\n-\t\t}\n-\t\tposn += size;\n-\t} while (posn < objsize);\n+\t*objsize = stream.total_out;\n+\treturn buf;\n+}\n \n-\tif (map)\n-\t\tmunmap(map, objsize);\n-\tif (temp_obj)\n-\t\tfree(temp_obj);\n+int write_sha1_to_fd(int fd, const unsigned char *sha1)\n+{\n+\tint retval;\n+\tunsigned long objsize;\n+\tvoid *buf = map_sha1_file_internal(sha1, &objsize);\n \n-\treturn 0;\n+\tif (buf) {\n+\t\tretval = write_buffer(fd, buf, objsize);\n+\t\tmunmap(buf, objsize);\n+\t\treturn retval;\n+\t}\n+\n+\tbuf = repack_object(sha1, &objsize);\n+\tretval = write_buffer(fd, buf, objsize);    \n+\tfree(buf);\n+\treturn retval;\n }\n \n int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,\n@@ -1579,7 +1595,8 @@ int write_sha1_from_fd(const unsigned ch\n \t\t\t\tSHA1_Update(&c, discard, sizeof(discard) -\n \t\t\t\t\t    stream.avail_out);\n \t\t\t} while (stream.avail_in && ret == Z_OK);\n-\t\t\twrite(local, buffer, *bufposn - stream.avail_in);\n+\t\t\tif (write_buffer(local, buffer, *bufposn - stream.avail_in) < 0)\n+\t\t\t\tdie(\"unable to write sha1 file\");\n \t\t\tmemmove(buffer, buffer + *bufposn - stream.avail_in,\n \t\t\t\tstream.avail_in);\n \t\t\t*bufposn = stream.avail_in;\n"},{"id":"20640","messageId":"E1Fixs4-0005pD-10@moooo.ath.cx","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0605240820560.5623@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"Matthias Lederhofer","fromEmail":"matled@gmx.net","sentAt":"2006-05-24T18:14:12Z","receivedAt":"2006-05-24T18:14:12Z","isPatch":false,"sender":{"key":"matled@gmx.net","avatar":null},"body":"> checking for partial writes\nJust out of interest: is this to be safe on any OS or should this\nbe checked always?\n\n> +\t\tsize = write(fd, buf, len);\n> +\t\tif (!size)\n> +\t\t\treturn error(\"file write: disk full\");\nShouldn't write to a full disk return -1 with ENOSPC?\n"},{"id":"20642","messageId":"Pine.LNX.4.64.0605241145490.5623@g5.osdl.org","threadId":"4279","inReplyTo":"E1Fixs4-0005pD-10@moooo.ath.cx","subject":"Re: Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-24T18:52:22Z","receivedAt":"2006-05-24T18:52:22Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 24 May 2006, Matthias Lederhofer wrote:\n\n> > checking for partial writes\n>\n> Just out of interest: is this to be safe on any OS or should this\n> be checked always?\n\nAny POSIX-conformant OS/filesystem should always do a full write for a \nregular file, unless a serious error happens.\n\nHOWEVER. \n\nIn practice, you can get partial writes at least over NFS (hey, it may not \nbe posix, but it's _common_) when the filesystem has been mounted soft \n(and/or interruptible). And obviously if your file descriptor isn't a \nregular file, you can easily get partial writes.\n\nDoing the loop is always safe, so it's worth doing it that way.\n\n> > +\t\tsize = write(fd, buf, len);\n> > +\t\tif (!size)\n> > +\t\t\treturn error(\"file write: disk full\");\n>\n> Shouldn't write to a full disk return -1 with ENOSPC?\n\nIn that case, the \"size < 0\" check will catch it. The \"return zero for \nfull\" case is an alternate error return (it happens for block device files \nat the end, it could happen for other things too). So the \"returns zero \nmeans full\" is the portable/safe thing to do.\n\n\t\tLinus\n"},{"id":"20647","messageId":"7vslmz5ewt.fsf@assigned-by-dhcp.cox.net","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0605240820560.5623@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-24T20:46:58Z","receivedAt":"2006-05-24T20:46:58Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> ... On the other hand, from a longer-term \n> maintenance standpoint and from a \"be much more careful when doing file \n> writes\" standpoint, I think it's worth it.\n>\n> The re-write is \"obviously correct\" (famous last words) and is mostly \n> just moving code around and getting rid of a few temporaries that become \n> unnecessary as a result.\n>\n> The patch looks a bit messy: the changes aren't actually that big, but the \n> split-up and the resulting re-indentation makes the patch fairly \n> unreadable, so the cleanups are more obvious when you look at the \n> before-and-after side by side rather than when looking at the unified \n> diff..)\n\nI usually work in text-only terminal, but with the above\nwarning, I did this:\n\n\tgit cat-file -p HEAD^:sha1_file.c >/var/tmp/1\n        xxdiff /var/tmp/1 sha1_file.c\n        \nwith ignorespace and stuff enabled.  It was very pleasant to\nread the changes that way, especially around write_sha1_to_fd()\nvs repack_object().  xxdiff is my new friend.\n"},{"id":"20653","messageId":"Pine.LNX.4.64.0605241631340.5623@g5.osdl.org","threadId":"4279","inReplyTo":"7vslmz5ewt.fsf@assigned-by-dhcp.cox.net","subject":"Re: Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-05-24T23:35:18Z","receivedAt":"2006-05-24T23:35:18Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 24 May 2006, Junio C Hamano wrote:\n>\n> It was very pleasant to read the changes that way, especially around \n> write_sha1_to_fd() vs repack_object().  xxdiff is my new friend.\n\nI think \"kompare\" (the KDE diff tool) is nicer.\n\nI'm tolf xxdiff integrates with some of the other SCM tools well (svn and \ntla), so it people use xxdiff, maybe it could support the git way of doing \nthings too..\n\n\t\tLinus\n"},{"id":"20656","messageId":"7virnv3qi6.fsf@assigned-by-dhcp.cox.net","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0605241631340.5623@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-25T00:19:29Z","receivedAt":"2006-05-25T00:19:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> On Wed, 24 May 2006, Junio C Hamano wrote:\n>>\n>> It was very pleasant to read the changes that way, especially around \n>> write_sha1_to_fd() vs repack_object().  xxdiff is my new friend.\n>\n> I think \"kompare\" (the KDE diff tool) is nicer.\n\nI'd love to give it a whirl, but aptitude says it will consume\n73.5MB diskspace to install it, with download size 22.4MB, which\nmakes me go ... hmmmm (my machines are currently KDE free so the\nabove counts slurping in the kdelibs essentials).  \n"},{"id":"20657","messageId":"BAYC1-PASMTP1121D710ADAA95C7B2D8E4AE990@CEZ.ICE","threadId":"4279","inReplyTo":"7virnv3qi6.fsf@assigned-by-dhcp.cox.net","subject":"Re: Clean up sha1 file writing","fromName":"Sean","fromEmail":"seanlkml@sympatico.ca","sentAt":"2006-05-25T00:31:08Z","receivedAt":"2006-05-25T00:31:08Z","isPatch":false,"sender":{"key":"seanlkml@sympatico.ca","avatar":"https://gravatar.com/avatar/f92923f54fc08c401fc59b71829d4b89e9b8087fbba45ff87c82e6a83aee02ae?d=mp&s=160"},"body":"On Wed, 24 May 2006 17:19:29 -0700\nJunio C Hamano <junkio@cox.net> wrote:\n\n> Linus Torvalds <torvalds@osdl.org> writes:\n> \n> > On Wed, 24 May 2006, Junio C Hamano wrote:\n> >>\n> >> It was very pleasant to read the changes that way, especially around \n> >> write_sha1_to_fd() vs repack_object().  xxdiff is my new friend.\n> >\n> > I think \"kompare\" (the KDE diff tool) is nicer.\n> \n> I'd love to give it a whirl, but aptitude says it will consume\n> 73.5MB diskspace to install it, with download size 22.4MB, which\n> makes me go ... hmmmm (my machines are currently KDE free so the\n> above counts slurping in the kdelibs essentials).  \n> \n\n\"meld\" works great too, and lets you do hunk-level merging etc; very\nhandy.  The bash <( ... )  feature is quite handy too, it will create\na temp file for you and clean it up afterward.\n\n$ meld sha1_file.c <(git cat-file -p c2f493a4ae:sha1_file.c)\n\nSean\n"},{"id":"20658","messageId":"20060525012232.GA14486@coredump.intra.peff.net","threadId":"4279","inReplyTo":"20060524203108.70b6c596.seanlkml@sympatico.ca","subject":"[PATCH] cat-file: document -p option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2006-05-25T01:22:32Z","receivedAt":"2006-05-25T01:22:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"---\nOn Wed, May 24, 2006 at 08:31:08PM -0400, Sean wrote:\n> $ meld sha1_file.c <(git cat-file -p c2f493a4ae:sha1_file.c)\n\nI had never seen the -p option, and it wasn't in the Documentation. Let\nme know if I've gotten its function completely wrong. :)\n\n-Peff\n\n Documentation/git-cat-file.txt |    9 +++++++--\n 1 files changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt\nindex 504eb1b..5e9cbf8 100644\n--- a/Documentation/git-cat-file.txt\n+++ b/Documentation/git-cat-file.txt\n@@ -8,12 +8,12 @@ git-cat-file - Provide content or type i\n \n SYNOPSIS\n --------\n-'git-cat-file' [-t | -s | -e | <type>] <object>\n+'git-cat-file' [-t | -s | -e | -p | <type>] <object>\n \n DESCRIPTION\n -----------\n Provides content or type of objects in the repository. The type\n-is required unless '-t' is used to find the object type,\n+is required unless '-t' or '-p' is used to find the object type,\n or '-s' is used to find the object size.\n \n OPTIONS\n@@ -33,6 +33,9 @@ OPTIONS\n \tSuppress all output; instead exit with zero status if <object>\n \texists and is a valid object.\n \n+-p::\n+\tPretty-print the contents of <object> based on its type.\n+\n <type>::\n \tTypically this matches the real type of <object> but asking\n \tfor a type that can trivially be dereferenced from the given\n@@ -49,6 +52,8 @@ If '-s' is specified, the size of the <o\n \n If '-e' is specified, no output.\n \n+If '-p' is specified, the contents of <object> are pretty-printed.\n+\n Otherwise the raw (though uncompressed) contents of the <object> will\n be returned.\n \n-- \n1.3.3.g4d548\n"},{"id":"20738","messageId":"7virntqrdt.fsf@assigned-by-dhcp.cox.net","threadId":"4279","inReplyTo":"7virnv3qi6.fsf@assigned-by-dhcp.cox.net","subject":"Re: Clean up sha1 file writing","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-26T05:36:30Z","receivedAt":"2006-05-26T05:36:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n>> I think \"kompare\" (the KDE diff tool) is nicer.\n>\n> I'd love to give it a whirl, but aptitude says it will consume\n> 73.5MB diskspace to install it, with download size 22.4MB, which\n> makes me go ... hmmmm (my machines are currently KDE free so the\n> above counts slurping in the kdelibs essentials).  \n\nIt indeed is nicer ;-).  I got a good laugh watching it smoothly\nmove the inserted hunk as I scrolled down.\n"},{"id":"21114","messageId":"44808710.1080000@zytor.com","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0605241145490.5623@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"H. Peter Anvin","fromEmail":"hpa@zytor.com","sentAt":"2006-06-02T18:44:32Z","receivedAt":"2006-06-02T18:44:32Z","isPatch":false,"sender":{"key":"hpa@zytor.com","avatar":null},"body":"Linus Torvalds wrote:\n> \n> On Wed, 24 May 2006, Matthias Lederhofer wrote:\n> \n>>> checking for partial writes\n>> Just out of interest: is this to be safe on any OS or should this\n>> be checked always?\n> \n> Any POSIX-conformant OS/filesystem should always do a full write for a \n> regular file, unless a serious error happens.\n> \n\nActually, at least Linux won't, if the object is larger than 2 GB on a 64-bit system :)\n\n\t-hpa\n"},{"id":"21116","messageId":"Pine.LNX.4.64.0606021416040.5498@g5.osdl.org","threadId":"4279","inReplyTo":"44808710.1080000@zytor.com","subject":"Re: Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-06-02T21:17:02Z","receivedAt":"2006-06-02T21:17:02Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 2 Jun 2006, H. Peter Anvin wrote:\n> Linus Torvalds wrote:\n> > \n> > Any POSIX-conformant OS/filesystem should always do a full write for a\n> > regular file, unless a serious error happens.\n> > \n> \n> Actually, at least Linux won't, if the object is larger than 2 GB on a 64-bit\n> system :)\n\nYeah, true.\n\nIn the end, you should always have the loop. That way, you never have to \nworry about what kind of file descriptor it is, what kind of filesystem \nyou're running on, and what the limits of ssize_t might be.\n\n\t\tLinus\n"},{"id":"21215","messageId":"4483259A.7090806@zytor.com","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0606021416040.5498@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"H. Peter Anvin","fromEmail":"hpa@zytor.com","sentAt":"2006-06-04T18:25:30Z","receivedAt":"2006-06-04T18:25:30Z","isPatch":false,"sender":{"key":"hpa@zytor.com","avatar":null},"body":"Linus Torvalds wrote:\n> \n> On Fri, 2 Jun 2006, H. Peter Anvin wrote:\n>> Linus Torvalds wrote:\n>>> Any POSIX-conformant OS/filesystem should always do a full write for a\n>>> regular file, unless a serious error happens.\n>>>\n>> Actually, at least Linux won't, if the object is larger than 2 GB on a 64-bit\n>> system :)\n> \n> Yeah, true.\n> \n> In the end, you should always have the loop. That way, you never have to \n> worry about what kind of file descriptor it is, what kind of filesystem \n> you're running on, and what the limits of ssize_t might be.\n> \n\nOr if you're getting a SIGWINCH in the middle of it.\n\nAny POSIX system will interrupt the transfer and return a short read on \nreceiving a signal.\n\n\t-hpa\n"},{"id":"21216","messageId":"Pine.LNX.4.64.0606041136180.5498@g5.osdl.org","threadId":"4279","inReplyTo":"4483259A.7090806@zytor.com","subject":"Re: Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-06-04T18:39:16Z","receivedAt":"2006-06-04T18:39:16Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 4 Jun 2006, H. Peter Anvin wrote:\n> \n> Or if you're getting a SIGWINCH in the middle of it.\n> \n> Any POSIX system will interrupt the transfer and return a short read on\n> receiving a signal.\n\nOnly for interruptible fd's, though, which normally a real \"file\" won't \nbe.\n\n\t\tLinus\n"},{"id":"21217","messageId":"Pine.LNX.4.64.0606041139310.5498@g5.osdl.org","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0606041136180.5498@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-06-04T18:40:54Z","receivedAt":"2006-06-04T18:40:54Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sun, 4 Jun 2006, Linus Torvalds wrote:\n> \n> On Sun, 4 Jun 2006, H. Peter Anvin wrote:\n> > \n> > Or if you're getting a SIGWINCH in the middle of it.\n> > \n> > Any POSIX system will interrupt the transfer and return a short read on\n> > receiving a signal.\n> \n> Only for interruptible fd's, though, which normally a real \"file\" won't \n> be.\n\nAnd _usually_ only if you actually have a SIGWINCH handler.\n\nAlthough older Linux kernels were broken in this regard. They'd interrupt \na socket/pipe read or write even for a signal that ended up being ignored.\n\nSo it's absolutely the case that having the loop is always the safer thing \nto do, and it's never the _wrong_ thing to do.\n\n\t\tLinus\n"},{"id":"21219","messageId":"44832EFC.4030507@zytor.com","threadId":"4279","inReplyTo":"Pine.LNX.4.64.0606041139310.5498@g5.osdl.org","subject":"Re: Clean up sha1 file writing","fromName":"H. Peter Anvin","fromEmail":"hpa@zytor.com","sentAt":"2006-06-04T19:05:32Z","receivedAt":"2006-06-04T19:05:32Z","isPatch":false,"sender":{"key":"hpa@zytor.com","avatar":null},"body":"Linus Torvalds wrote:\n> \n> On Sun, 4 Jun 2006, Linus Torvalds wrote:\n>> On Sun, 4 Jun 2006, H. Peter Anvin wrote:\n>>> Or if you're getting a SIGWINCH in the middle of it.\n>>>\n>>> Any POSIX system will interrupt the transfer and return a short read on\n>>> receiving a signal.\n>> Only for interruptible fd's, though, which normally a real \"file\" won't \n>> be.\n> \n> And _usually_ only if you actually have a SIGWINCH handler.\n> \n> Although older Linux kernels were broken in this regard. They'd interrupt \n> a socket/pipe read or write even for a signal that ended up being ignored.\n> \n> So it's absolutely the case that having the loop is always the safer thing \n> to do, and it's never the _wrong_ thing to do.\n> \n\nRight.  I tend to think of it as implementation-defined the cases where \nit happen to be safe, with the one exception of transactions which are \nsmaller than PIPE_BUF that are directed to a pipe.\n\n\t-hpa\n"}]}