@@ -67,7 +67,8 @@ func (ua *Unarchiver) Unarchive(archiveStream io.Reader, destination string) err
6767 if file .Mode ()& os .ModeSymlink != 0 {
6868 return writeNewSymbolicLink (path , file .LinkTarget )
6969 }
70- return writeNewHardLink (path , file .LinkTarget )
70+ target := filepath .Join (destination , file .LinkTarget )
71+ return writeNewHardLink (path , target )
7172 }
7273
7374 f , err := file .Open ()
@@ -132,6 +133,20 @@ func writeNewHardLink(fpath string, target string) error {
132133 return fmt .Errorf ("%s: making directory for file: %v" , fpath , err )
133134 }
134135
136+ // The unarchiving process is unordered, and a hardlinked file's target may not yet exist.
137+ // Create it. writeNewFile() will overwrite it later, which is okay.
138+ if ! fileExists (target ) {
139+ err = os .MkdirAll (filepath .Dir (target ), 0755 )
140+ if err != nil {
141+ return fmt .Errorf ("%s: making directory for file: %v" , target , err )
142+ }
143+ f , err := os .Create (target )
144+ if err != nil {
145+ return fmt .Errorf ("%s: creating target file: %v" , target , err )
146+ }
147+ f .Close ()
148+ }
149+
135150 err = os .Link (target , fpath )
136151 if err != nil {
137152 return fmt .Errorf ("%s: making hard link for: %v" , fpath , err )
0 commit comments