File bsc1200657.patch of Package tar.25515

From 49b9f54ff66d126c4c0d58ccfbc2b85f96f845fc Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 31 Mar 2022 18:26:03 -0700
Subject: [PATCH] Retry file creation more aggressively
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* src/extract.c (maybe_recoverable): When deciding whether to
retry file creation, don’t insist on our making intermediate
subdirectories; it’s OK if some other process made them.
Problem reported by James Abbatiello in:
https://lists.gnu.org/r/bug-tar/2022-03/msg00000.html
---
 src/extract.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: tar-1.34/src/extract.c
===================================================================
--- tar-1.34.orig/src/extract.c
+++ tar-1.34/src/extract.c
@@ -645,9 +645,9 @@ fixup_delayed_set_stat (char const *src,
    it's because some required directory was not present, and if so,
    create all required directories.  Return zero if all the required
    directories were created, nonzero (issuing a diagnostic) otherwise.
-   Set *INTERDIR_MADE if at least one directory was created.  */
+   */
 static int
-make_directories (char *file_name, bool *interdir_made)
+make_directories (char *file_name)
 {
   char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
   char *cursor;	        	/* points into the file name */
@@ -689,7 +689,6 @@ make_directories (char *file_name, bool
 			  desired_mode, AT_SYMLINK_NOFOLLOW);
 
 	  print_for_mkdir (file_name, cursor - file_name, desired_mode);
-	  *interdir_made = true;
 	}
       else if (errno == EEXIST)
 	status = 0;
@@ -829,8 +828,11 @@ maybe_recoverable (char *file_name, bool
 
     case ENOENT:
       /* Attempt creating missing intermediate directories.  */
-      if (make_directories (file_name, interdir_made) == 0 && *interdir_made)
-	return RECOVER_OK;
+      if (make_directories (file_name) == 0)
+             {
+               *interdir_made = true;
+               return RECOVER_OK;
+             }
       break;
 
     default:
@@ -1329,7 +1331,7 @@ extract_file (char *file_name, int typef
    first. If it doesn't exist, there is no matching entry in the list.
    Otherwise, look for the entry in list which has the matching dev
    and ino numbers.
-   
+
    This approach avoids scanning the singly-linked list in obvious cases
    and does not rely on comparing file names, which may differ for
    various reasons (e.g. relative vs. absolute file names).
@@ -1342,14 +1344,14 @@ find_delayed_link_source (char const *na
 
   if (!delayed_link_head)
     return NULL;
-  
+
   if (fstatat (chdir_fd, name, &st, AT_SYMLINK_NOFOLLOW))
     {
       if (errno != ENOENT)
 	stat_error (name);
       return NULL;
     }
-  
+
   for (dl = delayed_link_head; dl; dl = dl->next)
     {
       if (dl->dev == st.st_dev && dl->ino == st.st_ino)
@@ -1357,7 +1359,7 @@ find_delayed_link_source (char const *na
     }
   return dl;
 }
-  
+
 /* Create a placeholder file with name FILE_NAME, which will be
    replaced after other extraction is done by a symbolic link if
    IS_SYMLINK is true, and by a hard link otherwise.  Set
@@ -1385,7 +1387,7 @@ create_placeholder_file (char *file_name
 	   */
 	  return 0;
 	}
-      
+
       switch (maybe_recoverable (file_name, false, interdir_made))
 	{
 	case RECOVER_OK:
@@ -1467,7 +1469,7 @@ extract_link (char *file_name, int typef
   char const *link_name;
   int rc;
   struct delayed_link *dl;
-  
+
   link_name = current_stat_info.link_name;
 
   if (! absolute_names_option && contains_dot_dot (link_name))
@@ -1475,7 +1477,7 @@ extract_link (char *file_name, int typef
   dl = find_delayed_link_source (link_name);
   if (dl)
     return create_placeholder_file (file_name, false, &interdir_made, dl);
-  
+
   do
     {
       struct stat st1, st2;
@@ -1697,7 +1699,7 @@ prepare_to_extract (char const *file_nam
 
     case GNUTYPE_VOLHDR:
       return false;
-      
+
     case GNUTYPE_MULTIVOL:
       ERROR ((0, 0,
 	      _("%s: Cannot extract -- file is continued from another volume"),
@@ -1753,7 +1755,7 @@ prepare_to_extract (char const *file_nam
 	}
     }
   *fun = extractor;
-  
+
   return true;
 }
 
@@ -1934,12 +1936,11 @@ rename_directory (char *src, char *dst)
   else
     {
       int e = errno;
-      bool interdir_made;
 
       switch (e)
 	{
 	case ENOENT:
-	  if (make_directories (dst, &interdir_made) == 0)
+	  if (make_directories (dst) == 0)
 	    {
 	      if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
 		return true;
openSUSE Build Service is sponsored by