+ status = close (fd);
+ if (status < 0)
+ close_error (file_name);
+
+ if (to_command_option)
+ sys_wait_command ();
+ else
+ set_stat (file_name, ¤t_stat_info, NULL, 0,
+ (old_files_option == OVERWRITE_OLD_FILES ?
+ UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
+ typeflag);
+
+ return status;
+}
+
+/* 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
+ *INTERDIR_MADE if an intermediate directory is made in the
+ process. */
+
+static int
+create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
+{
+ int fd;
+ struct stat st;
+
+ while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
+ if (! maybe_recoverable (file_name, interdir_made))
+ break;
+
+ if (fd < 0)
+ open_error (file_name);
+ else if (fstat (fd, &st) != 0)
+ {
+ stat_error (file_name);
+ close (fd);
+ }
+ else if (close (fd) != 0)
+ close_error (file_name);
+ else
+ {
+ struct delayed_set_stat *h;
+ struct delayed_link *p =
+ xmalloc (offsetof (struct delayed_link, target)
+ + strlen (current_stat_info.link_name)
+ + 1);
+ p->next = delayed_link_head;
+ delayed_link_head = p;
+ p->dev = st.st_dev;
+ p->ino = st.st_ino;
+ p->mtime = get_stat_mtime (&st);
+ p->is_symlink = is_symlink;
+ if (is_symlink)
+ {
+ p->uid = current_stat_info.stat.st_uid;
+ p->gid = current_stat_info.stat.st_gid;
+ }
+ p->sources = xmalloc (offsetof (struct string_list, string)
+ + strlen (file_name) + 1);
+ p->sources->next = 0;
+ strcpy (p->sources->string, file_name);
+ strcpy (p->target, current_stat_info.link_name);
+
+ h = delayed_set_stat_head;
+ if (h && ! h->after_links
+ && strncmp (file_name, h->file_name, h->file_name_len) == 0
+ && ISSLASH (file_name[h->file_name_len])
+ && (last_component (file_name) == file_name + h->file_name_len + 1))
+ {
+ do