* EAGAIN?
@ 2005-12-19 10:07 Junio C Hamano
2005-12-19 19:46 ` EAGAIN? Linus Torvalds
0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2005-12-19 10:07 UTC (permalink / raw)
To: git; +Cc: torvalds
I am embarrassed to ask this in public, but anyway.
I was looking at "git grep -n EAGAIN" output and found that many
places check "errno == EAGAIN" without checking "errno ==
EINTR", both for read(2) and write(2). I feel that EAGAIN is
probably not that useful (it probably would not hurt us, though)
because we do not set up nonblocking ourselves, but I am
wondering if there is particular reason to only check EAGAIN but
not EINTR, or if they are just cut and paste errors.
apply.c:: read checks EAGAIN only, write checks both.
cat-file.c: write checks EAGAIN only.
copy.c:: read checks EAGAIN only, write checks both.
mktag.c:: read checks EAGAIN only.
pkt-line.c:: both read and write checks both.
tar-tree.c:: write checks EAGAIN only.
unpack-objects.c:: both read and write checks both.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: EAGAIN?
2005-12-19 10:07 EAGAIN? Junio C Hamano
@ 2005-12-19 19:46 ` Linus Torvalds
2005-12-19 22:23 ` EAGAIN? H. Peter Anvin
0 siblings, 1 reply; 6+ messages in thread
From: Linus Torvalds @ 2005-12-19 19:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Mon, 19 Dec 2005, Junio C Hamano wrote:
>
> I was looking at "git grep -n EAGAIN" output and found that many
> places check "errno == EAGAIN" without checking "errno ==
> EINTR", both for read(2) and write(2).
I suspect it's mostly in my code. It's a stupid quirk of mine.
You might as well delete those thing, but yes, if you want to replace them
with testing both EAGAIN and EINTR, go right ahead.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: EAGAIN?
2005-12-19 19:46 ` EAGAIN? Linus Torvalds
@ 2005-12-19 22:23 ` H. Peter Anvin
2005-12-20 0:55 ` [PATCH] xread/xwrite: do not worry about EINTR at calling sites Junio C Hamano
0 siblings, 1 reply; 6+ messages in thread
From: H. Peter Anvin @ 2005-12-19 22:23 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
Linus Torvalds wrote:
>
> On Mon, 19 Dec 2005, Junio C Hamano wrote:
>
>>I was looking at "git grep -n EAGAIN" output and found that many
>>places check "errno == EAGAIN" without checking "errno ==
>>EINTR", both for read(2) and write(2).
>
>
> I suspect it's mostly in my code. It's a stupid quirk of mine.
>
> You might as well delete those thing, but yes, if you want to replace them
> with testing both EAGAIN and EINTR, go right ahead.
>
It might be that some of those should either be replaced by fwrite/fread
or there should be a generic wrapper (usually called xwrite/xread).
-hpa
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] xread/xwrite: do not worry about EINTR at calling sites.
2005-12-19 22:23 ` EAGAIN? H. Peter Anvin
@ 2005-12-20 0:55 ` Junio C Hamano
2005-12-20 10:40 ` Johannes Schindelin
0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2005-12-20 0:55 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: Linus Torvalds, git
"H. Peter Anvin" <hpa@zytor.com> writes:
> Linus Torvalds wrote:
>> On Mon, 19 Dec 2005, Junio C Hamano wrote:
>>
>>>I was looking at "git grep -n EAGAIN" output and found that many
>>>places check "errno == EAGAIN" without checking "errno ==
>>>EINTR", both for read(2) and write(2).
>> I suspect it's mostly in my code. It's a stupid quirk of mine.
>> You might as well delete those thing, but yes, if you want to
>> replace them with testing both EAGAIN and EINTR, go right ahead.
>>
>
> It might be that some of those should either be replaced by fwrite/fread
> or there should be a generic wrapper (usually called xwrite/xread).
Good idea. Something like this I suppose....
-- >8 --
We had errno==EINTR check after read(2)/write(2) sprinkled all
over the places, always doing continue. Consolidate them into
xread()/xwrite() wrapper routines.
Credits for suggestion goes to HPA -- bugs are mine.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
apply.c | 23 ++++++-----------------
cat-file.c | 4 +---
copy.c | 19 +++++++------------
csum-file.c | 4 +---
git-compat-util.h | 22 ++++++++++++++++++++++
mktag.c | 9 ++-------
pkt-line.c | 11 +++--------
tar-tree.c | 4 +---
unpack-objects.c | 13 +++----------
9 files changed, 46 insertions(+), 63 deletions(-)
7c59f627268cd446fc7e1df9847dd1e2178072da
diff --git a/apply.c b/apply.c
index 1742ab2..d5e7bfd 100644
--- a/apply.c
+++ b/apply.c
@@ -84,14 +84,11 @@ static void *read_patch_file(int fd, uns
buffer = xrealloc(buffer, alloc);
nr = alloc - size;
}
- nr = read(fd, buffer + size, nr);
+ nr = xread(fd, buffer + size, nr);
if (!nr)
break;
- if (nr < 0) {
- if (errno == EAGAIN)
- continue;
+ if (nr < 0)
die("git-apply: read returned %s", strerror(errno));
- }
size += nr;
}
*sizep = size;
@@ -1006,13 +1003,8 @@ static int read_old_data(struct stat *st
return error("unable to open %s", path);
got = 0;
for (;;) {
- int ret = read(fd, buf + got, size - got);
- if (ret < 0) {
- if (errno == EAGAIN)
- continue;
- break;
- }
- if (!ret)
+ int ret = xread(fd, buf + got, size - got);
+ if (ret <= 0)
break;
got += ret;
}
@@ -1600,12 +1592,9 @@ static int try_create_file(const char *p
if (fd < 0)
return -1;
while (size) {
- int written = write(fd, buf, size);
- if (written < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
+ int written = xwrite(fd, buf, size);
+ if (written < 0)
die("writing file %s: %s", path, strerror(errno));
- }
if (!written)
die("out of space writing file %s", path);
buf += written;
diff --git a/cat-file.c b/cat-file.c
index 7594108..96d66b4 100644
--- a/cat-file.c
+++ b/cat-file.c
@@ -55,10 +55,8 @@ int main(int argc, char **argv)
die("git-cat-file %s: bad file", argv[2]);
while (size > 0) {
- long ret = write(1, buf, size);
+ long ret = xwrite(1, buf, size);
if (ret < 0) {
- if (errno == EAGAIN)
- continue;
/* Ignore epipe */
if (errno == EPIPE)
break;
diff --git a/copy.c b/copy.c
index e1cd5d0..7100eed 100644
--- a/copy.c
+++ b/copy.c
@@ -6,32 +6,27 @@ int copy_fd(int ifd, int ofd)
int len;
char buffer[8192];
char *buf = buffer;
- len = read(ifd, buffer, sizeof(buffer));
+ len = xread(ifd, buffer, sizeof(buffer));
if (!len)
break;
if (len < 0) {
int read_error;
- if (errno == EAGAIN)
- continue;
read_error = errno;
close(ifd);
return error("copy-fd: read returned %s",
strerror(read_error));
}
- while (1) {
- int written = write(ofd, buf, len);
+ while (len) {
+ int written = xwrite(ofd, buf, len);
if (written > 0) {
buf += written;
len -= written;
- if (!len)
- break;
}
- if (!written)
+ else if (!written)
return error("copy-fd: write returned 0");
- if (errno == EAGAIN || errno == EINTR)
- continue;
- return error("copy-fd: write returned %s",
- strerror(errno));
+ else
+ return error("copy-fd: write returned %s",
+ strerror(errno));
}
}
close(ifd);
diff --git a/csum-file.c b/csum-file.c
index c66b9eb..5f9249a 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -15,7 +15,7 @@ static int sha1flush(struct sha1file *f,
void *buf = f->buffer;
for (;;) {
- int ret = write(f->fd, buf, count);
+ int ret = xwrite(f->fd, buf, count);
if (ret > 0) {
buf += ret;
count -= ret;
@@ -25,8 +25,6 @@ static int sha1flush(struct sha1file *f,
}
if (!ret)
die("sha1 file '%s' write error. Out of diskspace", f->name);
- if (errno == EAGAIN || errno == EINTR)
- continue;
die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
}
}
diff --git a/git-compat-util.h b/git-compat-util.h
index ead0ede..0c98c99 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -84,6 +84,28 @@ static inline void *xcalloc(size_t nmemb
return ret;
}
+static inline ssize_t xread(int fd, void *buf, size_t len)
+{
+ ssize_t nr;
+ while (1) {
+ nr = read(fd, buf, len);
+ if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ continue;
+ return nr;
+ }
+}
+
+static inline ssize_t xwrite(int fd, const void *buf, size_t len)
+{
+ ssize_t nr;
+ while (1) {
+ nr = write(fd, buf, len);
+ if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
+ continue;
+ return nr;
+ }
+}
+
/* Sane ctype - no locale, and works with signed chars */
#undef isspace
#undef isdigit
diff --git a/mktag.c b/mktag.c
index 97e270a..fc6a9bf 100644
--- a/mktag.c
+++ b/mktag.c
@@ -116,14 +116,9 @@ int main(int argc, char **argv)
// Read the signature
size = 0;
for (;;) {
- int ret = read(0, buffer + size, MAXSIZE - size);
- if (!ret)
+ int ret = xread(0, buffer + size, MAXSIZE - size);
+ if (ret <= 0)
break;
- if (ret < 0) {
- if (errno == EAGAIN)
- continue;
- break;
- }
size += ret;
}
diff --git a/pkt-line.c b/pkt-line.c
index 6947304..bb3bab0 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -19,7 +19,7 @@
static void safe_write(int fd, const void *buf, unsigned n)
{
while (n) {
- int ret = write(fd, buf, n);
+ int ret = xwrite(fd, buf, n);
if (ret > 0) {
buf += ret;
n -= ret;
@@ -27,8 +27,6 @@ static void safe_write(int fd, const voi
}
if (!ret)
die("write error (disk full?)");
- if (errno == EAGAIN || errno == EINTR)
- continue;
die("write error (%s)", strerror(errno));
}
}
@@ -68,12 +66,9 @@ static void safe_read(int fd, void *buff
int n = 0;
while (n < size) {
- int ret = read(fd, buffer + n, size - n);
- if (ret < 0) {
- if (errno == EINTR || errno == EAGAIN)
- continue;
+ int ret = xread(fd, buffer + n, size - n);
+ if (ret < 0)
die("read error (%s)", strerror(errno));
- }
if (!ret)
die("unexpected EOF");
n += ret;
diff --git a/tar-tree.c b/tar-tree.c
index bacb23a..96bd143 100644
--- a/tar-tree.c
+++ b/tar-tree.c
@@ -34,10 +34,8 @@ struct path_prefix {
static void reliable_write(void *buf, unsigned long size)
{
while (size > 0) {
- long ret = write(1, buf, size);
+ long ret = xwrite(1, buf, size);
if (ret < 0) {
- if (errno == EAGAIN)
- continue;
if (errno == EPIPE)
exit(0);
die("git-tar-tree: %s", strerror(errno));
diff --git a/unpack-objects.c b/unpack-objects.c
index cfd61ae..5c5cb12 100644
--- a/unpack-objects.c
+++ b/unpack-objects.c
@@ -31,12 +31,10 @@ static void * fill(int min)
offset = 0;
}
do {
- int ret = read(0, buffer + len, sizeof(buffer) - len);
+ int ret = xread(0, buffer + len, sizeof(buffer) - len);
if (ret <= 0) {
if (!ret)
die("early EOF");
- if (errno == EAGAIN || errno == EINTR)
- continue;
die("read error on input: %s", strerror(errno));
}
len += ret;
@@ -299,14 +297,9 @@ int main(int argc, char **argv)
/* Write the last part of the buffer to stdout */
while (len) {
- int ret = write(1, buffer + offset, len);
- if (!ret)
- break;
- if (ret < 0) {
- if (errno == EAGAIN || errno == EINTR)
- continue;
+ int ret = xwrite(1, buffer + offset, len);
+ if (ret <= 0)
break;
- }
len -= ret;
offset += ret;
}
--
0.99.9.GIT
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] xread/xwrite: do not worry about EINTR at calling sites.
2005-12-20 0:55 ` [PATCH] xread/xwrite: do not worry about EINTR at calling sites Junio C Hamano
@ 2005-12-20 10:40 ` Johannes Schindelin
2005-12-20 18:59 ` Linus Torvalds
0 siblings, 1 reply; 6+ messages in thread
From: Johannes Schindelin @ 2005-12-20 10:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: H. Peter Anvin, Linus Torvalds, git
Hi,
On Mon, 19 Dec 2005, Junio C Hamano wrote:
> +static inline ssize_t xwrite(int fd, const void *buf, size_t len)
> +{
> + ssize_t nr;
> + while (1) {
> + nr = write(fd, buf, len);
> + if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
> + continue;
> + return nr;
> + }
> +}
In another project I'm working on, a user insisted that on Solaris 2.7,
write(2) sometimes returns ENOENT when it really means "try again". I
cannot verify, since I don't have Solaris 2.7.
Ciao,
Dscho
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] xread/xwrite: do not worry about EINTR at calling sites.
2005-12-20 10:40 ` Johannes Schindelin
@ 2005-12-20 18:59 ` Linus Torvalds
0 siblings, 0 replies; 6+ messages in thread
From: Linus Torvalds @ 2005-12-20 18:59 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, H. Peter Anvin, git
On Tue, 20 Dec 2005, Johannes Schindelin wrote:
>
> In another project I'm working on, a user insisted that on Solaris 2.7,
> write(2) sometimes returns ENOENT when it really means "try again". I
> cannot verify, since I don't have Solaris 2.7.
That would be either a very confused user or a terminally sick Solaris
kernel. In either case, not worth fixing.
Linus
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-12-20 19:00 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-19 10:07 EAGAIN? Junio C Hamano
2005-12-19 19:46 ` EAGAIN? Linus Torvalds
2005-12-19 22:23 ` EAGAIN? H. Peter Anvin
2005-12-20 0:55 ` [PATCH] xread/xwrite: do not worry about EINTR at calling sites Junio C Hamano
2005-12-20 10:40 ` Johannes Schindelin
2005-12-20 18:59 ` Linus Torvalds
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).