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

[PATCH 3/4] config.c: avoid xmmap error messages

From
Jeff King <peff@peff.net>
Date
May 28, 2015, 07:56 UTC
Message-ID
<20150528075614.GC23395@peff.net>
In-Reply-To
<20150528075142.GB3688@peff.net>

The config-writing code uses xmmap to map the existing config file, which will die if the map fails. This has two downsides:

  1. The error message is not very helpful, as it lacks any
     context about the file we are mapping:
       $ mkdir foo
       $ git config --file=foo some.key value
       fatal: Out of memory? mmap failed: No such device
  2. We normally do not die in this code path; instead, we'd
     rather report the error and return an appropriate exit
     status (which is part of the public interface
     documented in git-config.1).

This patch introduces a "gentle" form of xmmap which lets us produce our own error message. We do not want to use mmap directly, because we would like to use the other compatibility elements of xmmap (e.g., handling 0-length maps portably).

The end result is:
    $ git.compile config --file=foo some.key value
    error: unable to mmap 'foo': No such device
    $ echo $?
    3
Signed-off-by: Jeff King <peff@peff.net>
---
 config.c          | 11 +++++++++--
 git-compat-util.h |  1 +
 sha1_file.c       | 15 +++++++++++----
 3 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/config.c b/config.c
index 6917100..e7dc155 100644
--- a/config.c
+++ b/config.c
@@ -2053,8 +2053,15 @@ int git_config_set_multivar_in_file(const char *config_filename,
 
 		fstat(in_fd, &st);
 		contents_sz = xsize_t(st.st_size);
-		contents = xmmap(NULL, contents_sz, PROT_READ,
-			MAP_PRIVATE, in_fd, 0);
+		contents = xmmap_gently(NULL, contents_sz, PROT_READ,
+					MAP_PRIVATE, in_fd, 0);
+		if (contents == MAP_FAILED) {
+			error("unable to mmap '%s': %s",
+			      config_filename, strerror(errno));
+			ret = CONFIG_INVALID_FILE;
+			contents = NULL;
+			goto out_free;
+		}
 		close(in_fd);
 
 		if (chmod(lock->filename.buf, st.st_mode & 07777) < 0) {
diff --git a/git-compat-util.h b/git-compat-util.h
index 17584ad..0cc7ae8 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -718,6 +718,7 @@ extern char *xstrndup(const char *str, size_t len);
 extern void *xrealloc(void *ptr, size_t size);
 extern void *xcalloc(size_t nmemb, size_t size);
 extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
+extern void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 extern ssize_t xread(int fd, void *buf, size_t len);
 extern ssize_t xwrite(int fd, const void *buf, size_t len);
 extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
diff --git a/sha1_file.c b/sha1_file.c
index ccc6dac..73e0bc0 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -707,8 +707,8 @@ static void mmap_limit_check(size_t length)
 		    (uintmax_t)length, (uintmax_t)limit);
 }
 
-void *xmmap(void *start, size_t length,
-	int prot, int flags, int fd, off_t offset)
+void *xmmap_gently(void *start, size_t length,
+		  int prot, int flags, int fd, off_t offset)
 {
 	void *ret;
 
@@ -719,12 +719,19 @@ void *xmmap(void *start, size_t length,
 			return NULL;
 		release_pack_memory(length);
 		ret = mmap(start, length, prot, flags, fd, offset);
-		if (ret == MAP_FAILED)
-			die_errno("Out of memory? mmap failed");
 	}
 	return ret;
 }
 
+void *xmmap(void *start, size_t length,
+	int prot, int flags, int fd, off_t offset)
+{
+	void *ret = xmmap_gently(start, length, prot, flags, fd, offset);
+	if (ret == MAP_FAILED)
+			die_errno("Out of memory? mmap failed");
+	return ret;
+}
+
 void close_pack_windows(struct packed_git *p)
 {
 	while (p->windows) {
-- 
2.4.2.668.gc3b1ade.dirty
Previous: Jeff KingNext: Jeff King
Message 15 of 20 in “Bug: .gitconfig folder”
  1. JorgeMay 27, 2015
  2. Junio C HamanoMay 27, 2015
  3. Jeff KingMay 27, 2015
  4. Stefan BellerMay 27, 2015
  5. Jeff KingMay 28, 2015
  6. Junio C HamanoMay 27, 2015
  7. Jeff KingMay 28, 2015
  8. 1/4 read-cache.c: drop PROT_WRITE from mmap of indexJeff King, May 28, 2015
  9. 2/4 config.c: fix mmap leak when writing configJeff King, May 28, 2015
  10. config.c: fix writing config files on Windows network sharesKarsten Blees, Jun 30, 2015
  11. Torsten BögershausenJun 30, 2015
  12. Jeff KingJun 30, 2015
  13. Johannes SchindelinJun 30, 2015
  14. Jeff KingJun 30, 2015
  15. 3/4 config.c: avoid xmmap error messagesJeff King, May 28, 2015
  16. 4/4 config.c: rewrite ENODEV into EISDIR when mmap failsJeff King, May 28, 2015
  17. Junio C HamanoMay 28, 2015
  18. Jeff KingMay 28, 2015
  19. Junio C HamanoMay 28, 2015
  20. Junio C HamanoMay 28, 2015

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.