Ejemplo n.º 1
0
func lockFcntl(name string) (io.Closer, error) {
	fi, err := os.Stat(name)
	if err == nil && fi.Size() > 0 {
		return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
	}

	f, err := os.Create(name)
	if err != nil {
		return nil, fmt.Errorf("Lock Create of %s failed: %v", name, err)
	}

	err = unix.FcntlFlock(f.Fd(), unix.F_SETLK, &unix.Flock_t{
		Type:   unix.F_WRLCK,
		Whence: int16(os.SEEK_SET),
		Start:  0,
		Len:    0, // 0 means to lock the entire file.
		Pid:    0, // only used by F_GETLK
	})

	if err != nil {
		f.Close()
		return nil, fmt.Errorf("Lock FcntlFlock of %s failed: %v", name, err)
	}
	return &unlocker{f: f, abs: name}, nil
}
Ejemplo n.º 2
0
// Acquire acquires a lock on a file for the duration of the process. This method
// is reentrant.
func Acquire(path string) error {
	lock.Lock()
	defer lock.Unlock()
	var err error
	if lockfile, err = os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600); err != nil {
		return err
	}

	opts := unix.Flock_t{Type: unix.F_WRLCK}
	if err := unix.FcntlFlock(lockfile.Fd(), unix.F_SETLKW, &opts); err != nil {
		return err
	}
	return nil
}
Ejemplo n.º 3
0
// TestFcntlFlock tests whether the file locking structure matches
// the calling convention of each kernel.
func TestFcntlFlock(t *testing.T) {
	name := filepath.Join(os.TempDir(), "TestFcntlFlock")
	fd, err := unix.Open(name, unix.O_CREAT|unix.O_RDWR|unix.O_CLOEXEC, 0)
	if err != nil {
		t.Fatalf("Open failed: %v", err)
	}
	defer unix.Unlink(name)
	defer unix.Close(fd)
	flock := unix.Flock_t{
		Type:  unix.F_RDLCK,
		Start: 0, Len: 0, Whence: 1,
	}
	if err := unix.FcntlFlock(uintptr(fd), unix.F_GETLK, &flock); err != nil {
		t.Fatalf("FcntlFlock failed: %v", err)
	}
}