(target *FileInformation, targetStat os.FileInfo)
| 288 | } |
| 289 | |
| 290 | func (a *Archiver) tarFile(target *FileInformation, targetStat os.FileInfo) error { |
| 291 | var err error |
| 292 | filepath := path.Join(a.basePath, target.Name) |
| 293 | if targetStat.Mode()&os.ModeSymlink == os.ModeSymlink { |
| 294 | if filepath, err = os.Readlink(filepath); err != nil { |
| 295 | return nil |
| 296 | } |
| 297 | |
| 298 | targetStat, err = os.Stat(filepath) |
| 299 | if err != nil || targetStat.IsDir() { |
| 300 | // We ignore open file and just treat it as okay |
| 301 | return nil |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | // Case regular file |
| 306 | f, err := os.Open(filepath) |
| 307 | if err != nil { |
| 308 | // We ignore open file and just treat it as okay |
| 309 | return nil |
| 310 | } |
| 311 | defer f.Close() |
| 312 | |
| 313 | hdr, err := tar.FileInfoHeader(targetStat, filepath) |
| 314 | if err != nil { |
| 315 | return errors.Wrap(err, "create tar file info header") |
| 316 | } |
| 317 | hdr.Name = target.Name |
| 318 | hdr.Uid = 0 |
| 319 | hdr.Gid = 0 |
| 320 | hdr.Mode = fillGo18FileTypeBits(int64(chmodTarEntry(os.FileMode(hdr.Mode))), targetStat) |
| 321 | hdr.ModTime = time.Unix(target.Mtime, 0) |
| 322 | |
| 323 | if err := a.writer.WriteHeader(hdr); err != nil { |
| 324 | return errors.Wrap(err, "tar write header") |
| 325 | } |
| 326 | |
| 327 | // nothing more to do for non-regular |
| 328 | if !targetStat.Mode().IsRegular() { |
| 329 | return nil |
| 330 | } |
| 331 | |
| 332 | copied, err := io.CopyN(a.writer, f, targetStat.Size()) |
| 333 | if err != nil { |
| 334 | return errors.Wrap(err, "tar copy file") |
| 335 | } else if copied != targetStat.Size() { |
| 336 | return errors.New("tar: file truncated during read") |
| 337 | } |
| 338 | |
| 339 | a.writtenFiles[target.Name] = target |
| 340 | return nil |
| 341 | } |
| 342 | |
| 343 | const ( |
| 344 | modeISDIR = 040000 // Directory |
no test coverage detected