code: func (l *UpdateableFileLock) Update(contents io.Reader) error {
  	lockDir := filepath.Dir(l.path)
  	newFile, err := ioutil.TempFile(lockDir, fmt.Sprintf(".%s", filepath.Base(l.path)))
  	if err != nil {
  		return err
  	}
  	defer newFile.Close()
  	if err := newFile.Chmod(l.perms); err != nil {
  		os.Remove(newFile.Name())
  		return err
  	}
  
  	_, err = io.Copy(newFile, contents)
  	if err != nil {
  		os.Remove(newFile.Name())
  		return err
  	}
  
  	newFileLock, err := lock.TryExclusiveLock(newFile.Name(), lock.RegFile)
  	if err != nil {
  		os.Remove(newFile.Name())
  		return fmt.Errorf("could not lock tmpfile: %v", err)
  	}
  
  	l.lockLock.Lock()
  	defer l.lockLock.Unlock()
  
  	if !l.isLocked {
  		os.Remove(newFile.Name())
  		return AlreadyUnlockedErr
  	}
  	// Overwrite the old lock with our new one that has the correct contents
  	err = os.Rename(newFile.Name(), l.path)
  	if err != nil {
  		return err
  	}
  	// Lock overwritten, update our internal state while we still hold the mutex
  	oldLock := l.lock
  	l.lock = newFileLock
  	oldLock.Unlock()
  	return nil
  }
docs: // Update writes the given contents into the filelock atomically