Skip to content

use LE call instead if the call is implemented #87

@github-actions

Description

@github-actions

offset of the byte following the last byte that was read.

offset of in_fd

// TODO: use LE call instead if the call is implemented

	return n, nil
}

func Err2ad() (eadd *int) {
	r0, _, _ := CallLeFuncWithErr(GetZosLibVec() + SYS___ERR2AD<<4)
	eadd = (*int)(unsafe.Pointer(r0))
	return
}

func ZosConsolePrintf(format string, v ...interface{}) (int, error) {
	type __cmsg struct {
		_            uint16
		_            [2]uint8
		__msg_length uint32
		__msg        uintptr
		_            [4]uint8
	}
	msg := fmt.Sprintf(format, v...)
	strptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&msg)).Data)
	len := (*reflect.StringHeader)(unsafe.Pointer(&msg)).Len
	cmsg := __cmsg{__msg_length: uint32(len), __msg: uintptr(strptr)}
	cmd := uint32(0)
	runtime.EnterSyscall()
	rc, err2, err1 := CallLeFuncWithErr(GetZosLibVec()+SYS_____CONSOLE_A<<4, uintptr(unsafe.Pointer(&cmsg)), 0, uintptr(unsafe.Pointer(&cmd)))
	runtime.ExitSyscall()
	if rc != 0 {
		return 0, fmt.Errorf("%s (errno2=0x%x)\n", err1.Error(), err2)
	}
	return 0, nil
}
func ZosStringToEbcdicBytes(str string, nullterm bool) (ebcdicBytes []byte) {
	if nullterm {
		ebcdicBytes = []byte(str + "\x00")
	} else {
		ebcdicBytes = []byte(str)
	}
	A2e(ebcdicBytes)
	return
}
func ZosEbcdicBytesToString(b []byte, trimRight bool) (str string) {
	res := make([]byte, len(b))
	copy(res, b)
	E2a(res)
	if trimRight {
		str = string(bytes.TrimRight(res, " \x00"))
	} else {
		str = string(res)
	}
	return
}

func fdToPath(dirfd int) (path string, err error) {
	var buffer [1024]byte
	// w_ctrl()
	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
	if ret == 0 {
		zb := bytes.IndexByte(buffer[:], 0)
		if zb == -1 {
			zb = len(buffer)
		}
		// __e2a_l()
		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
		return string(buffer[:zb]), nil
	}
	// __errno()
	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
		[]uintptr{}))))
	// __errno2()
	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
		[]uintptr{}))
	// strerror_r()
	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
	if ret == 0 {
		zb := bytes.IndexByte(buffer[:], 0)
		if zb == -1 {
			zb = len(buffer)
		}
		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
	} else {
		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
	}
}

func impl_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
	var _p0 *byte
	_p0, err = BytePtrFromString(path)
	if err != nil {
		return
	}
	runtime.EnterSyscall()
	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS___MKFIFOAT_A<<4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
	runtime.ExitSyscall()
	if int64(r0) == -1 {
		err = errnoErr2(e1, e2)
	}
	return
}

//go:nosplit
func get_MkfifoatAddr() *(func(dirfd int, path string, mode uint32) (err error))

var Mkfifoat = enter_Mkfifoat

func enter_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
	funcref := get_MkfifoatAddr()
	if funcptrtest(GetZosLibVec()+SYS___MKFIFOAT_A<<4, "") == 0 {
		*funcref = impl_Mkfifoat
	} else {
		*funcref = legacy_Mkfifoat
	}
	return (*funcref)(dirfd, path, mode)
}

func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) {
	dirname, err := ZosFdToPath(dirfd)
	if err != nil {
		return err
	}
	return Mkfifo(dirname+"/"+path, mode)
}

//sys	Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT
//sys	Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT
//sys	Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT

func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) {
	runtime.EnterSyscall()
	r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg)
	runtime.ExitSyscall()
	val = int(r0)
	if int64(r0) == -1 {
		err = errnoErr2(e1, e2)
	}
	return
}

func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) {
	switch op.(type) {
	case *Flock_t:
		err = FcntlFlock(fd, cmd, op.(*Flock_t))
		if err != nil {
			ret = -1
		}
		return
	case int:
		return FcntlInt(fd, cmd, op.(int))
	case *F_cnvrt:
		return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt))))
	case unsafe.Pointer:
		return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer)))
	default:
		return -1, EINVAL
	}
	return
}

func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
	if raceenabled {
		raceReleaseMerge(unsafe.Pointer(&ioSync))
	}
	return sendfile(outfd, infd, offset, count)
}

func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
	// TODO: use LE call instead if the call is implemented
	originalOffset, err := Seek(infd, 0, SEEK_CUR)
	if err != nil {
		return -1, err
	}
	//start reading data from in_fd
	if offset != nil {
		_, err := Seek(infd, *offset, SEEK_SET)
		if err != nil {
			return -1, err
		}
	}

	buf := make([]byte, count)
	readBuf := make([]byte, 0)
	var n int = 0
	for i := 0; i < count; i += n {
		n, err := Read(infd, buf)
		if n == 0 {
			if err != nil {
				return -1, err
			} else { // EOF
				break
			}
		}
		readBuf = append(readBuf, buf...)
		buf = buf[0:0]
	}

	n2, err := Write(outfd, readBuf)
	if err != nil {
		return -1, err
	}

	//When sendfile() returns, this variable will be set to the
	// offset of the byte following the last byte that was read.
	if offset != nil {
		*offset = *offset + int64(n)
		// If offset is not NULL, then sendfile() does not modify the file
		// offset of in_fd
		_, err := Seek(infd, originalOffset, SEEK_SET)
		if err != nil {
			return -1, err
		}
	}
	return n2, nil
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions