* Clean up write_in_full() users
@ 2007-01-12 4:23 Linus Torvalds
2007-01-12 4:33 ` Shawn O. Pearce
0 siblings, 1 reply; 4+ messages in thread
From: Linus Torvalds @ 2007-01-12 4:23 UTC (permalink / raw)
To: Git Mailing List, Junio C Hamano
With the new-and-improved write_in_full() semantics, where a partial write
simply always returns a real error (and always sets 'errno' when that
happens, including for the disk full case), a lot of the callers of
write_in_full() were just unnecessarily complex.
In particular, there's no reason to ever check for a zero length or
return: if the length was zero, we'll return zero, otherwise, if a disk
full resulted in the actual write() system call returning zero the
write_in_full() logic would have correctly turned that into a negative
return value, with 'errno' set to ENOSPC.
I really wish every "write_in_full()" user would just check against "<0"
now, but this fixes the nasty and stupid ones.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
I actually think "read_in_full()" should get the same loving tender care
too, for all the same reasons. I think "read_or_die()" is totally broken.
Anybody who uses "read_or_die()" is buggy by definition, since it will do
a partial read AND NOT RETURN ANY INDICATION THAT IT WAS PARTIAL!
Can I please ask people who do these idiotic cleanups to get their act
together?
I'll send a patch for that next, but I looked at "write_in_full()" first,
for historical reasons.
diff --git a/sha1_file.c b/sha1_file.c
index 18dd89b..2a5be53 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1618,14 +1618,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
static int write_buffer(int fd, const void *buf, size_t len)
{
- ssize_t size;
-
- if (!len)
- return 0;
- size = write_in_full(fd, buf, len);
- if (!size)
- return error("file write: disk full");
- if (size < 0)
+ if (write_in_full(fd, buf, len) < 0)
return error("file write error (%s)", strerror(errno));
return 0;
}
diff --git a/write_or_die.c b/write_or_die.c
index 488de72..1224cac 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -58,14 +58,7 @@ int write_in_full(int fd, const void *buf, size_t count)
void write_or_die(int fd, const void *buf, size_t count)
{
- ssize_t written;
-
- if (!count)
- return;
- written = write_in_full(fd, buf, count);
- if (written == 0)
- die("disk full?");
- else if (written < 0) {
+ if (write_in_full(fd, buf, count) < 0) {
if (errno == EPIPE)
exit(0);
die("write error (%s)", strerror(errno));
@@ -74,16 +67,7 @@ void write_or_die(int fd, const void *buf, size_t count)
int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)
{
- ssize_t written;
-
- if (!count)
- return 1;
- written = write_in_full(fd, buf, count);
- if (written == 0) {
- fprintf(stderr, "%s: disk full?\n", msg);
- return 0;
- }
- else if (written < 0) {
+ if (write_in_full(fd, buf, count) < 0) {
if (errno == EPIPE)
exit(0);
fprintf(stderr, "%s: write error (%s)\n",
@@ -96,16 +80,7 @@ int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg)
int write_or_whine(int fd, const void *buf, size_t count, const char *msg)
{
- ssize_t written;
-
- if (!count)
- return 1;
- written = write_in_full(fd, buf, count);
- if (written == 0) {
- fprintf(stderr, "%s: disk full?\n", msg);
- return 0;
- }
- else if (written < 0) {
+ if (write_in_full(fd, buf, count) < 0) {
fprintf(stderr, "%s: write error (%s)\n",
msg, strerror(errno));
return 0;
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: Clean up write_in_full() users
2007-01-12 4:23 Clean up write_in_full() users Linus Torvalds
@ 2007-01-12 4:33 ` Shawn O. Pearce
2007-01-12 4:43 ` Linus Torvalds
0 siblings, 1 reply; 4+ messages in thread
From: Shawn O. Pearce @ 2007-01-12 4:33 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Git Mailing List, Junio C Hamano
Linus Torvalds <torvalds@osdl.org> wrote:
> I actually think "read_in_full()" should get the same loving tender care
> too, for all the same reasons. I think "read_or_die()" is totally broken.
> Anybody who uses "read_or_die()" is buggy by definition, since it will do
> a partial read AND NOT RETURN ANY INDICATION THAT IT WAS PARTIAL!
AFAIK the only user of read_or_die is sha1_file.c when it reads in
the 12 byte pack header and the 20 byte pack trailer to "quickly"
verify the packfile is sane before using it. If I recall correctly
it was correct when I created it, but the read_in_full refactoring
changed it.
--
Shawn.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Clean up write_in_full() users
2007-01-12 4:33 ` Shawn O. Pearce
@ 2007-01-12 4:43 ` Linus Torvalds
2007-01-12 14:37 ` Morten Welinder
0 siblings, 1 reply; 4+ messages in thread
From: Linus Torvalds @ 2007-01-12 4:43 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Git Mailing List, Junio C Hamano
On Thu, 11 Jan 2007, Shawn O. Pearce wrote:
>
> AFAIK the only user of read_or_die is sha1_file.c when it reads in
> the 12 byte pack header and the 20 byte pack trailer to "quickly"
> verify the packfile is sane before using it. If I recall correctly
> it was correct when I created it, but the read_in_full refactoring
> changed it.
Well, I just sent a patch to hopefully fix it, but I also think that the
whole function is really misdesigned.
The thing is, "write_or_die()" actually makes sense. If you get a write
error, things are really seriously broken, and it makes a lot of sense to
just say "things are totally broken".
HOWEVER. The same thing is not true of a partial read. If a read doesn't
succeed fully, the most _common_ case is that a file is truncated, and it
does generally NOT make sense to just die and say "partial file".
So for a write error, it's ok to say "ok, I can't write, I'm dead".
For a read error, at the very least you have to say WHICH FILE couldn't be
read, because it's usually a matter of some file just being too short, not
some system-wide problem.
Looking at the two call-sites of "read_or_die()", they really are better
off not dying, or if they died, the caller should have passed in the
_reason_ (ie the name of the pack-file), or should have just used a
non-dying version and tested the return value and written a message of its
own.
But at least the function now WORKS after the patch I just sent out. Which
it didn't do before.
Linus
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Clean up write_in_full() users
2007-01-12 4:43 ` Linus Torvalds
@ 2007-01-12 14:37 ` Morten Welinder
0 siblings, 0 replies; 4+ messages in thread
From: Morten Welinder @ 2007-01-12 14:37 UTC (permalink / raw)
To: GIT Mailing List
> The thing is, "write_or_die()" actually makes sense.
Except for a library. Calling exit is very unappealing in that case and trying
to change die to use longjmp is even less appealing.
M.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-01-12 14:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-12 4:23 Clean up write_in_full() users Linus Torvalds
2007-01-12 4:33 ` Shawn O. Pearce
2007-01-12 4:43 ` Linus Torvalds
2007-01-12 14:37 ` Morten Welinder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox