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

[PATCH v2 02/20] safe_create_leading_directories(): set errno on SCLD_EXISTS

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Feb 25, 2016, 13:16 UTC
Message-ID
<bf790258cb69fc63fd6ebaddd249face1ff2bdf6.1456405698.git.mhagger@alum.mit.edu>
In-Reply-To
<cover.1456405698.git.mhagger@alum.mit.edu>

The exit path for SCLD_EXISTS wasn't setting errno, which some callers use to generate error messages for the user. Fix the problem and document that the function sets errno correctly to help avoid similar regressions in the future.

While we're at it, document the difference between safe_create_leading_directories() and safe_create_leading_directories_const().

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 cache.h     | 10 ++++++++--
 sha1_file.c |  4 +++-
 2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/cache.h b/cache.h
index 26640b4..7d3f80c 100644
--- a/cache.h
+++ b/cache.h
@@ -950,8 +950,9 @@ int adjust_shared_perm(const char *path);
 
 /*
  * Create the directory containing the named path, using care to be
- * somewhat safe against races.  Return one of the scld_error values
- * to indicate success/failure.
+ * somewhat safe against races. Return one of the scld_error values to
+ * indicate success/failure. On error, set errno to describe the
+ * problem.
  *
  * SCLD_VANISHED indicates that one of the ancestor directories of the
  * path existed at one point during the function call and then
@@ -959,6 +960,11 @@ int adjust_shared_perm(const char *path);
  * directory while we were working.  To be robust against this kind of
  * race, callers might want to try invoking the function again when it
  * returns SCLD_VANISHED.
+ *
+ * The non _const version of this function temporarily modifies its
+ * path parameter while it is working but restores it before exiting.
+ * The _const version does not modify path (at the cost of having to
+ * make a temporary scratch copy).
  */
 enum scld_error {
 	SCLD_OK = 0,
diff --git a/sha1_file.c b/sha1_file.c
index 568120e..94c6779 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -135,8 +135,10 @@ enum scld_error safe_create_leading_directories(char *path)
 		*slash = '\0';
 		if (!stat(path, &st)) {
 			/* path exists */
-			if (!S_ISDIR(st.st_mode))
+			if (!S_ISDIR(st.st_mode)) {
+				errno = ENOTDIR;
 				ret = SCLD_EXISTS;
+			}
 		} else if (mkdir(path, 0777)) {
 			if (errno == EEXIST &&
 			    !stat(path, &st) && S_ISDIR(st.st_mode))
-- 
2.7.0
Previous: Michael HaggertyNext: Michael Haggerty
Message 3 of 21 in “Delete directories left empty after ref deletion”
  1. 00/20 Delete directories left empty after ref deletionMichael Haggerty, Feb 25, 2016
  2. 01/20 safe_create_leading_directories_const(): preserve errnoMichael Haggerty, Feb 25, 2016
  3. 02/20 safe_create_leading_directories(): set errno on SCLD_EXISTSMichael Haggerty, Feb 25, 2016
  4. 03/20 raceproof_create_file(): new functionMichael Haggerty, Feb 25, 2016
  5. 04/20 lock_ref_sha1_basic(): use raceproof_create_file()Michael Haggerty, Feb 25, 2016
  6. 05/20 rename_tmp_log(): use raceproof_create_file()Michael Haggerty, Feb 25, 2016
  7. 06/20 rename_tmp_log(): improve error reportingMichael Haggerty, Feb 25, 2016
  8. 07/20 log_ref_setup(): separate code for create vs non-createMichael Haggerty, Feb 25, 2016
  9. 08/20 log_ref_setup(): improve robustness against racesMichael Haggerty, Feb 25, 2016
  10. 09/20 log_ref_setup(): pass the open file descriptor back to the callerMichael Haggerty, Feb 25, 2016
  11. 10/20 log_ref_write_1(): don't depend on logfileMichael Haggerty, Feb 25, 2016
  12. 11/20 log_ref_setup(): manage the name of the reflog file internallyMichael Haggerty, Feb 25, 2016
  13. 12/20 log_ref_write_1(): inline functionMichael Haggerty, Feb 25, 2016
  14. 13/20 try_remove_empty_parents(): rename parameter "name" -> "refname"Michael Haggerty, Feb 25, 2016
  15. 14/20 try_remove_empty_parents(): don't trash argument contentsMichael Haggerty, Feb 25, 2016
  16. 15/20 try_remove_empty_parents(): don't accommodate consecutive slashesMichael Haggerty, Feb 25, 2016
  17. 16/20 t5505: use "for-each-ref" to test for the non-existence of referencesMichael Haggerty, Feb 25, 2016
  18. 17/20 delete_ref_loose(): derive loose reference path from lockMichael Haggerty, Feb 25, 2016
  19. 18/20 delete_ref_loose(): inline functionMichael Haggerty, Feb 25, 2016
  20. 19/20 try_remove_empty_parents(): teach to remove parents of reflogs, tooMichael Haggerty, Feb 25, 2016
  21. 20/20 ref_transaction_commit(): clean up empty directoriesMichael Haggerty, Feb 25, 2016

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.