MCPcopy
hub / github.com/syncthing/syncthing / tempFileInWritableDir

Method tempFileInWritableDir

lib/model/sharedpullerstate.go:158–236  ·  view source on GitHub ↗

tempFileInWritableDir should only be called from tempFile.

(_ string)

Source from the content-addressed store, hash-verified

156
157// tempFileInWritableDir should only be called from tempFile.
158func (s *sharedPullerState) tempFileInWritableDir(_ string) error {
159 // The permissions to use for the temporary file should be those of the
160 // final file, except we need user read & write at minimum. The
161 // permissions will be set to the final value later, but in the meantime
162 // we don't want to have a temporary file with looser permissions than
163 // the final outcome.
164 mode := fs.FileMode(s.file.Permissions) | 0o600
165 if s.ignorePerms {
166 // When ignorePerms is set we use a very permissive mode and let the
167 // system umask filter it.
168 mode = 0o666
169 }
170
171 // Attempt to create the temp file
172 // RDWR because of issue #2994.
173 flags := fs.OptReadWrite
174 if s.reused == 0 {
175 flags |= fs.OptCreate | fs.OptExclusive
176 } else if !s.ignorePerms {
177 // With sufficiently bad luck when exiting or crashing, we may have
178 // had time to chmod the temp file to read only state but not yet
179 // moved it to its final name. This leaves us with a read only temp
180 // file that we're going to try to reuse. To handle that, we need to
181 // make sure we have write permissions on the file before opening it.
182 //
183 // When ignorePerms is set we trust that the permissions are fine
184 // already and make no modification, as we would otherwise override
185 // what the umask dictates.
186
187 if err := s.fs.Chmod(s.tempName, mode); err != nil {
188 return fmt.Errorf("setting perms on temp file: %w", err)
189 }
190 }
191 fd, err := s.fs.OpenFile(s.tempName, flags, mode)
192 if err != nil {
193 return fmt.Errorf("opening temp file: %w", err)
194 }
195
196 // Hide the temporary file
197 s.fs.Hide(s.tempName)
198
199 // Don't truncate symlink files, as that will mean that the path will
200 // contain a bunch of nulls.
201 if s.sparse && !s.file.IsSymlink() {
202 size := s.file.Size
203 // Trailer added to encrypted files
204 if len(s.file.Encrypted) > 0 {
205 size += encryptionTrailerSize(s.file)
206 }
207 // Truncate sets the size of the file. This creates a sparse file or a
208 // space reservation, depending on the underlying filesystem.
209 if err := fd.Truncate(size); err != nil {
210 // The truncate call failed. That can happen in some cases when
211 // space reservation isn't possible or over some network
212 // filesystems... This generally doesn't matter.
213
214 if s.reused > 0 {
215 // ... but if we are attempting to reuse a file we have a

Callers

nothing calls this directly

Calls 10

FileModeTypeAlias · 0.92
encryptionTrailerSizeFunction · 0.85
DebuglnMethod · 0.80
ChmodMethod · 0.65
OpenFileMethod · 0.65
HideMethod · 0.65
IsSymlinkMethod · 0.65
TruncateMethod · 0.65
CloseMethod · 0.65
RemoveMethod · 0.65

Tested by

no test coverage detected