// LockFile opens and locks the file at the given path - it will block and wait for unlock
347097
func LockFile(filelockpath string) (*os.File, error) {

	if true {
		// take advantage of Open and O_EXCL (man creat for more info)
		// the downside of this approach is that killing the application
		// will prevent file lockfile cleanup even if there is a defer os.Remove(lockfile)
	WAIT_FOR_LOCK:
		for {
			glog.V(2).Infof("locking file: %s", filelockpath)
			fp, err := os.OpenFile(filelockpath, syscall.O_RDWR|syscall.O_CREAT|syscall.O_EXCL, 0600)
			if err != nil {
				if !strings.Contains(err.Error(), syscall.EEXIST.Error()) {
					return nil, err
				}
			} else {
				glog.V(2).Infof("locked file: %s", filelockpath)
				return fp, nil
			}

			glog.Infof("waiting to lock file: %s", filelockpath)
			select {
			case <-time.After(1 * time.Second):
				continue WAIT_FOR_LOCK
			}
		}

		//return nil, fmt.Errorf("timed out waiting to lock file %s", filelockpath)
	} else {

		// other failed attempts to lock file using fcntl/flock/...
		fp, err := os.OpenFile(filelockpath, syscall.O_RDWR|syscall.O_CREAT, 0600)
		if err != nil {
			return nil, err
		}

		glog.V(2).Infof("locking file: %s", filelockpath)
		if false {
			// FIXME: this is not working from GO, but works from C - thread issue even when sync mutex is used
			var flp = C.CString(filelockpath)
			defer C.free(unsafe.Pointer(flp))
			rc := C.fd_lock(C.int(fp.Fd()), flp)
			if 0 != rc {
				return nil, fmt.Errorf("unable to lock file %s", filelockpath)
			}
			/*
				} else if false {
					// BEWARE: flock does not work when two hosts are NFS locking
					// flock tested and works on ubuntu: ext4, btrfs, NFS (same host)
					// flock tested on centos: tmpfs, ext4, btrfs, NFS (same host)
					if err := unix.Flock(int(fp.Fd()), unix.LOCK_EX); err != nil {
						return nil, err
					}
				} else if false {
					// FIXME: unix.FcntlFlock is not working - thread issue and NFS issue
					ft := unix.Flock_t{
						Type:   syscall.F_WRLCK,         //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
						Whence: int16(os.SEEK_SET),      // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
						Start:  0,                       // Starting offset for lock
						Len:    0,                       // Number of bytes to lock
						Pid:    int32(syscall.Getpid()), // PID of process blocking our lock (F_GETLK only)
					}
					glog.V(2).Infof("syscall.Flock_t %#v", ft)

					if err := unix.FcntlFlock(fp.Fd(), syscall.F_SETLKW, &ft); err != nil {
						return nil, err
					}
			*/
		} else if false {
			// FIXME: flock does not work when two hosts are NFS locking
			// flock tested and works on ubuntu: ext4, btrfs, NFS (same host)
			// flock tested on centos: tmpfs, ext4, btrfs, NFS (same host)
			if err := syscall.Flock(int(fp.Fd()), syscall.LOCK_EX); err != nil {
				return nil, err
			}
		} else if false {
			// FIXME: syscall.FcntlFlock is not working - thread issue and syscall issue and NFS issue
			ft := syscall.Flock_t{
				Type:   syscall.F_WRLCK,         //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
				Whence: int16(os.SEEK_SET),      // How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END
				Start:  0,                       // Starting offset for lock
				Len:    0,                       // Number of bytes to lock
				Pid:    int32(syscall.Getpid()), // PID of process blocking our lock (F_GETLK only)
			}
			glog.V(2).Infof("syscall.Flock_t %#v", ft)

			if err := syscall.FcntlFlock(fp.Fd(), syscall.F_SETLKW /* F_GETLK, F_SETLK, F_SETLKW */, &ft); err != nil {
				return nil, err
			}
		} else if false {
			// FIXME: syscall.FcntlFlock is not working - thread issue and syscall issue and NFS issue
			// This type matches C's "struct flock" defined in /usr/include/x86_64-linux-gnu/bits/fcntl.h
			k := struct {
				Type   uint32
				Whence uint32
				Start  uint64
				Len    uint64
				Pid    uint32
			}{
				Type:   syscall.F_WRLCK,
				Whence: uint32(os.SEEK_SET),
				Start:  0,
				Len:    0, // 0 means to lock the entire file.
				Pid:    uint32(os.Getpid()),
			}

			glog.V(2).Infof("mimic /usr/include/x86_64-linux-gnu/bits/fcntl.h syscall.Flock_t %#v", k)
			_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fp.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
			if errno != 0 {
				fp.Close()
				return nil, fmt.Errorf("syscall.Syscall error: %s", errno)
			}
		} else {
			return nil, fmt.Errorf("all filelocking implementations fail")
		}

		glog.V(2).Infof("locked  file: %s", filelockpath)
		return fp, nil
	}
}
1019789
func (fm *filesManager) unlockFile(file *file) {
	if !atomic.CompareAndSwapInt32(&file.state, fileInUse, fileOpened) {
		panic(fmt.Errorf("failed to switch state from fileInUse to fileOpened for file %q, state=%v",
			file.name, file.state))
	}
}
1059060
func (locker *MemoryLocker) LockUpload(id string) error {
	locker.mutex.Lock()
	defer locker.mutex.Unlock()

	// Ensure file is not locked
	if _, ok := locker.locks[id]; ok {
		return tusd.ErrFileLocked
	}

	locker.locks[id] = struct{}{}

	return nil
}
511589
func (fo *FileWriterOutput) openFile() (*os.File, error) {
	return os.OpenFile(fo.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
}
817129
func (l *FileLock) Unlock() error {
	return syscall.Flock(l.fd, syscall.LOCK_UN)
}
1238975
func (s *Server) unlock(ctx context.Context, lockPath string) error {
	s.mu.Lock()
	li, ok := s.locks[lockPath]
	s.mu.Unlock()
	if !ok {
		return vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "unlock: lock %v not held", lockPath)
	}

	// Try to unlock our lock. We will clean up our entry anyway.
	unlockErr := li.lock.Unlock()

	s.mu.Lock()
	delete(s.locks, lockPath)
	s.mu.Unlock()
	close(li.done)

	// Then try to remove the lock entirely. This will only work if
	// noone else has the lock.
	if err := li.lock.Destroy(); err != nil {
		// If someone else has the lock, we can't remove it,
		// but we don't need to.
		if err != api.ErrLockInUse {
			log.Warningf("failed to clean up lock file %v: %v", lockPath, err)
		}
	}

	return unlockErr
}
349168
func (f *LockPIDFile) Lock() (err error) {
	// make the parent directory
	_, err = os.Stat(filepath.Dir(f.name))
	if os.IsNotExist(err) {
		err = os.MkdirAll(filepath.Dir(f.name), 0700)
		if err != nil {
			return err
		}
	} else if err != nil {
		return err
	}

	if f.file, err = os.OpenFile(f.name, os.O_CREATE|os.O_RDWR, 0600); err != nil {
		return err
	}

	// LOCK_EX = exclusive
	// LOCK_NB = nonblocking
	if err = syscall.Flock(int(f.file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
		f.file.Close()
		f.file = nil
		return err
	}

	pid := os.Getpid()
	fmt.Fprintf(f.file, "%d", pid)
	f.file.Sync()

	f.log.Debugf("Locked pidfile %s for pid=%d", f.name, pid)

	return nil
}
649459
func (fm *filesManager) closeLockedFile(file *file) error {
	if !atomic.CompareAndSwapInt32(&file.state, fileInUse, fileClosing) {
		panic(fmt.Errorf("file %q is requested to be closed but was not locked by caller", file.name))
	}
	fm.Lock()
	err := fm.doClose(file)
	fm.Unlock()
	return err
}
1368347
func (d *FSDirectory) DeleteFile(name string) (err error) {
	d.EnsureOpen()
	if err = os.Remove(filepath.Join(d.path, name)); err == nil {
		d.staleFilesLock.Lock()
		defer d.staleFilesLock.Unlock()
		delete(d.staleFiles, name)
	}
	return
}
602712
func CloseFile(f *os.File) {
	if err := f.Close(); err != nil {
		glog.Warningf("unable to close file %s: %v", f.Name(), err)
	}
}
1158445
func OpenFile(path string) (*os.File, error) {
	newPath, err := NormalizePath(path)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	fi, err := os.Stat(newPath)
	if err != nil {
		return nil, trace.ConvertSystemError(err)
	}
	if fi.IsDir() {
		return nil, trace.BadParameter("%v is not a file", path)
	}
	f, err := os.Open(newPath)
	if err != nil {
		return nil, trace.ConvertSystemError(err)
	}
	return f, nil
}
536266
func (lf *lockFile) Close() error {
	lf.Lock()
	defer lf.Unlock()
	if lf.f == nil {
		return nil
	}
	spec := &syscall.Flock_t{
		Type:   syscall.F_UNLCK,
		Whence: int16(io.SeekStart),
		Start:  0,
		Len:    0, // 0 means to lock the entire file.
	}
	err := syscall.FcntlFlock(lf.f.Fd(), syscall.F_SETLK, spec)
	err = CloseFile(err, lf.f)
	lf.f = nil
	return err
}
857576
func LockedOpenFile(path string, flag int, perm os.FileMode) (*LockedFile, error) {
	return lockedOpenFile(path, flag, perm, syscall.F_SETLKW)
}
253476
func (fm *filesManager) lockFile(file *file) (bool, error) {
	if atomic.CompareAndSwapInt32(&file.state, fileOpened, fileInUse) {
		return true, nil
	}
	return false, fm.openFile(file)
}
1064195
func lockPath(path string) (uintptr, error) {
	if len(path) == 0 {
		return uintptr(syscall.InvalidHandle), syscall.ERROR_FILE_NOT_FOUND
	}
	pathp, err := syscall.UTF16PtrFromString(path)
	if err != nil {
		return uintptr(syscall.InvalidHandle), err
	}
	access := uint32(syscall.GENERIC_READ)
	sharemode := uint32(syscall.FILE_SHARE_READ)
	createmode := uint32(syscall.OPEN_EXISTING)
	flags := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS | syscall.FILE_FLAG_OPEN_REPARSE_POINT)
	fd, err := syscall.CreateFile(pathp, access, sharemode, nil, createmode, flags, 0)
	return uintptr(fd), err
}
1364418
func writeFile(path string, contents []byte) {
	handleError(ioutil.WriteFile(path, contents, 0640))
}
489896
func (c *Client) UnlockFile(path string, force bool) error {
	id, err := c.lockIdFromPath(path)
	if err != nil {
		return fmt.Errorf("Unable to get lock id: %v", err)
	}

	return c.UnlockFileById(id, force)
}