MCPcopy Index your code
hub / github.com/tailscale/tailscale / openFileOrSubstitute

Function openFileOrSubstitute

cmd/tailscale/cli/file.go:649–689  ·  view source on GitHub ↗
(dir, base string, action onConflict)

Source from the content-addressed store, hash-verified

647}
648
649func openFileOrSubstitute(dir, base string, action onConflict) (*os.File, error) {
650 targetFile := filepath.Join(dir, base)
651 f, err := os.OpenFile(targetFile, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644)
652 if err == nil {
653 return f, nil
654 }
655 // Something went wrong trying to open targetFile as a new file for writing.
656 switch action {
657 default:
658 // This should not happen.
659 return nil, fmt.Errorf("file issue. how to resolve this conflict? no one knows.")
660 case skipOnExist:
661 if _, statErr := os.Stat(targetFile); statErr == nil {
662 // we can stat a file at that path: so it already exists.
663 return nil, fmt.Errorf("refusing to overwrite file: %w", err)
664 }
665 return nil, fmt.Errorf("failed to write; %w", err)
666 case overwriteExisting:
667 // remove the target file and create it anew so we don't fall for an
668 // attacker who symlinks a known target name to a file he wants changed.
669 if err = os.Remove(targetFile); err != nil {
670 return nil, fmt.Errorf("unable to remove target file: %w", err)
671 }
672 if f, err = os.OpenFile(targetFile, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644); err != nil {
673 return nil, fmt.Errorf("unable to overwrite: %w", err)
674 }
675 return f, nil
676 case createNumberedFiles:
677 // It's possible the target directory or filesystem isn't writable by us,
678 // not just that the target file(s) already exists. For now, give up after
679 // a limited number of attempts. In future, maybe distinguish this case
680 // and follow in the style of https://tinyurl.com/chromium100
681 maxAttempts := 100
682 for i := 1; i < maxAttempts; i++ {
683 if f, err = os.OpenFile(numberedFileName(dir, base, i), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644); err == nil {
684 return f, nil
685 }
686 }
687 return nil, fmt.Errorf("unable to find a name for writing %v, final attempt: %w", targetFile, err)
688 }
689}
690
691func receiveFile(ctx context.Context, wf apitype.WaitingFile, dir string) (targetFile string, size int64, err error) {
692 rc, size, err := localClient.GetWaitingFile(ctx, wf.Name)

Callers 1

receiveFileFunction · 0.85

Calls 5

numberedFileNameFunction · 0.85
ErrorfMethod · 0.65
StatMethod · 0.65
RemoveMethod · 0.65
OpenFileMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…