//go:build unix

package vfs

import (
	
	

	
)

const (
	isUnix      = true
	_O_NOFOLLOW = unix.O_NOFOLLOW
)

func osAccess( string,  AccessFlag) error {
	var  uint32 // unix.F_OK
	switch  {
	case ACCESS_READWRITE:
		 = unix.R_OK | unix.W_OK
	case ACCESS_READ:
		 = unix.R_OK
	}
	return unix.Access(, )
}

func osReadAt( *os.File,  []byte,  int64) (int, error) {
	,  := .ReadAt(, )
	if ,  := .(unix.Errno);  {
		switch  {
		case
			unix.ERANGE,
			unix.EIO,
			unix.ENXIO:
			return , _IOERR_CORRUPTFS
		}
	}
	return , 
}

func osWriteAt( *os.File,  []byte,  int64) (int, error) {
	,  := .WriteAt(, )
	if ,  := .(unix.Errno);  &&  == unix.ENOSPC {
		return , _FULL
	}
	return , 
}

func osSetMode( *os.File,  string) error {
	,  := os.Stat()
	if  != nil {
		return 
	}
	.Chmod(.Mode())
	if ,  := .Sys().(*syscall.Stat_t);  {
		.Chown(int(.Uid), int(.Gid))
	}
	return nil
}

func osTestLock( *os.File, ,  int64) (int16, _ErrorCode) {
	 := unix.Flock_t{
		Type:  unix.F_WRLCK,
		Start: ,
		Len:   ,
	}
	for {
		 := unix.FcntlFlock(.Fd(), unix.F_GETLK, &)
		if  == nil {
			return .Type, _OK
		}
		if  != unix.EINTR {
			return 0, _IOERR_CHECKRESERVEDLOCK
		}
	}
}

func osLockErrorCode( error,  _ErrorCode) _ErrorCode {
	if  == nil {
		return _OK
	}
	if ,  := .(unix.Errno);  {
		switch  {
		case
			unix.EACCES,
			unix.EAGAIN,
			unix.EBUSY,
			unix.EINTR,
			unix.ENOLCK,
			unix.EDEADLK,
			unix.ETIMEDOUT:
			return _BUSY
		case unix.EPERM:
			return _PERM
		}
		// notest // usually EWOULDBLOCK == EAGAIN
		if  == unix.EWOULDBLOCK && unix.EWOULDBLOCK != unix.EAGAIN {
			return _BUSY
		}
	}
	return 
}