safeWrite writes the buffer to a file in a "safe" way, preventing loss of the contents of the file if it fails to write the new contents. This means that the file is not overwritten directly but by writing to the backup file first.
(path string, withSudo bool, newFile bool)
| 354 | // This means that the file is not overwritten directly but by writing to the |
| 355 | // backup file first. |
| 356 | func (b *SharedBuffer) safeWrite(path string, withSudo bool, newFile bool) (int, error) { |
| 357 | file, err := openFile(path, withSudo) |
| 358 | if err != nil { |
| 359 | return 0, err |
| 360 | } |
| 361 | |
| 362 | defer func() { |
| 363 | if newFile && err != nil { |
| 364 | os.Remove(path) |
| 365 | } |
| 366 | }() |
| 367 | |
| 368 | // Try to backup first before writing |
| 369 | backupName, resolveName, err := b.writeBackup(path) |
| 370 | if err != nil { |
| 371 | file.Close() |
| 372 | return 0, err |
| 373 | } |
| 374 | |
| 375 | // Backup saved, so cancel pending periodic backup, if any |
| 376 | delete(requestedBackups, b) |
| 377 | |
| 378 | b.forceKeepBackup = true |
| 379 | size := 0 |
| 380 | { |
| 381 | // If we failed to write or close, keep the backup we made |
| 382 | size, err = file.Write(b) |
| 383 | if err != nil { |
| 384 | file.Close() |
| 385 | return 0, util.OverwriteError{err, backupName} |
| 386 | } |
| 387 | |
| 388 | err = file.Close() |
| 389 | if err != nil { |
| 390 | return 0, util.OverwriteError{err, backupName} |
| 391 | } |
| 392 | } |
| 393 | b.forceKeepBackup = false |
| 394 | |
| 395 | if !b.keepBackup() { |
| 396 | b.removeBackup(backupName, resolveName) |
| 397 | } |
| 398 | |
| 399 | return size, err |
| 400 | } |
no test coverage detected