git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] strbuf_read_file(): preserve errno across close() call

From
Jeff King <peff@peff.net>
Date
Feb 23, 2018, 07:00 UTC
Message-ID
<20180223070053.GC19791@sigill.intra.peff.net>
In-Reply-To
<20180223064952.GB19791@sigill.intra.peff.net>
On Fri, Feb 23, 2018 at 01:49:52AM -0500, Jeff King wrote:
Show 19 quoted lines
> > +static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path)
> > +{
> > +	int fd;
> > +	ssize_t len;
> > +
> > +	fd = open(path, O_RDONLY);
> > +	if (fd < 0)
> > +		return error_errno(_("could not open '%s'"), path);
> > +	len = strbuf_read(sb, fd, 0);
> > +	close(fd);
> > +	if (len < 0)
> > +		return error(_("could not read '%s'."), path);
> > +	return len;
> > +}
> 
> If we were to use error_errno() in the second conditional here, we
> should take care not to clobber errno during the close(). I think
> strbuf_read_file() actually has the same problem, which might be worth
> fixing.
Here's a patch, while I'm thinking about it.

I notice that quite a few strbuf error paths may call strbuf_release(), too. Technically free() may clobber errno, too. I don't know if it's worth protecting against (IIRC POSIX is being amended to disallow this, but I have no idea how common it is in existing platforms).

-- >8 --
Subject: [PATCH] strbuf_read_file(): preserve errno across close() call

If we encounter a read error, the user may want to report it by looking at errno. However, our close() call may clobber errno, leading to confusing results. Let's save and restore it in the error case.

Signed-off-by: Jeff King <peff@peff.net>
---
 strbuf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/strbuf.c b/strbuf.c
index 1df674e919..5f138ed3c8 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -612,14 +612,18 @@ ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
 {
 	int fd;
 	ssize_t len;
+	int saved_errno;
 
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		return -1;
 	len = strbuf_read(sb, fd, hint);
+	saved_errno = errno;
 	close(fd);
-	if (len < 0)
+	if (len < 0) {
+		errno = saved_errno;
 		return -1;
+	}
 
 	return len;
 }
-- 
2.16.2.580.g96c83ce8ea
Previous: Jeff KingNext: René Scharfe
Message 4 of 8 in “sequencer: factor out strbuf_read_file_or_whine()”
  1. sequencer: factor out strbuf_read_file_or_whine()René Scharfe, Feb 22, 2018
  2. Junio C HamanoFeb 22, 2018
  3. Jeff KingFeb 23, 2018
  4. strbuf_read_file(): preserve errno across close() callJeff King, Feb 23, 2018
  5. René ScharfeFeb 23, 2018
  6. Junio C HamanoFeb 23, 2018
  7. René ScharfeFeb 23, 2018
  8. Jeff KingFeb 26, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.